Share via


粒狀延伸模組

粒紋延伸模組提供將額外行為新增至粒紋的方法。 您可以使用衍生自 IGrainExtension 的介面來擴充粒紋,將新的方法和功能新增至粒紋。

在本文中,您會看到兩個粒紋延伸模組的範例。 第一個範例示範如何將 Deactivate 方法新增至可用來停用粒紋的所有粒紋。 第二個範例示範如何將 GetStateSetState 方法新增至任何粒紋,讓您操作粒紋的內部狀態。

停用延伸模組範例

在此範例中,您將了解如何自動將 Deactivate 方法新增至所有粒紋。 方法可用來停用粒紋,並接受字串做為訊息參數。 Orleans 粒紋已經透過 IGrainManagementExtension 介面支援這項功能。 不過,此範例會示範如何自行新增這項功能或類似功能。

停用延伸模組介面

首先,定義包含 Deactivate 方法的 IGrainDeactivateExtension 介面。 介面必須衍生自 IGrainExtension

public interface IGrainDeactivateExtension : IGrainExtension
{
    Task Deactivate(string msg);
}

停用延伸模組實作

接下來,實作 GrainDeactivateExtension 類別,以提供 Deactivate 方法的實作。

若要存取目標粒紋,您可以從建構函式擷取 IGrainContext。 建立具有相依性插入的延伸模組時,會將其插入。

public sealed class GrainDeactivateExtension : IGrainDeactivateExtension
{
    private IGrainContext _context;

    public GrainDeactivateExtension(IGrainContext context)
    {
        _context = context;
    }

    public async Task Deactivate(string msg)
    {
        var reason = new DeactivationReason(DeactivationReasonCode.ApplicationRequested, msg);
        await _context.DeactivateAsync(reason);
    }
}

停用延伸模組註冊和使用方式

既然您已定義介面和實作,請在使用 AddGrainExtension 方法設定尋址接收器時,註冊延伸模組。

siloBuilder.AddGrainExtension<IGrainDeactivateExtension, GrainDeactivateExtension>();

若要在任何粒紋上使用延伸模組,請擷取延伸模組的參考,並呼叫 Deactivate 方法。

var grain = client.GetGrain<SomeExampleGrain>(someKey);
var grainReferenceAsInterface = grain.AsReference<IGrainDeactivateExtension>();

await grainReferenceAsInterface.Deactivate("Because, I said so...");

狀態操作延伸模組範例

在此範例中,您會了解如何透過延伸模組將 GetStateSetState 方法新增至任何粒紋,讓您操作粒紋的內部狀態。

狀態操作延伸模組介面

首先,定義 IGrainStateAccessor<T> 介面,其中包含 GetStateSetState 方法。 同樣地,這個介面必須衍生自 IGrainExtension

public interface IGrainStateAccessor<T> : IGrainExtension
{
    Task<T> GetState();
    Task SetState(T state);
}

一旦您有目標粒紋的存取權後,即可使用延伸模組來操作其狀態。 在此範例中,您會使用延伸模組來存取及修改目標粒紋內的特定整數狀態值。

狀態操作延伸模組實作

您使用的延伸模組是 IGrainStateAccessor<T>,其提供方法來取得及設定 T 類型的狀態值。 若要建立延伸模組,您可以在類別中實作介面,其建構函式中採用 gettersetter 做為引數。

public sealed class GrainStateAccessor<T> : IGrainStateAccessor<T>
{
    private readonly Func<T> _getter;
    private readonly Action<T> _setter;

    public GrainStateAccessor(Func<T> getter, Action<T> setter)
    {
        _getter = getter;
        _setter = setter;
    }

    public Task<T> GetState()
    {
        return Task.FromResult(_getter.Invoke());
    }

    public Task SetState(T state)
    {
        _setter.Invoke(state);
        return Task.CompletedTask;
    }
}

在上述實作中,GrainStateAccessor<T> 類別會採用其建構函式中的 gettersetter 引數。 這些委派可用來讀取及修改目標粒紋的狀態。 GetState() 方法會傳回 Task<TResult> 包裝 T 狀態的目前值,而 SetState(T state) 方法則會設定 T 狀態的新值。

狀態操作延伸模組註冊和使用方式

若要使用延伸模組來存取及修改目標粒紋的狀態,您必須註冊延伸模組,並在目標粒紋的 Grain.OnActivateAsync() 方法中設定其元件。

public override Task OnActivateAsync()
{
    // Retrieve the IGrainStateAccessor<T> extension
    var accessor = new GrainStateAccessor<int>(
        getter: () => this.Value,
        setter: value => this.Value = value);

    // Set the extension as a component of the target grain's context
    ((IGrainBase)this).GrainContext.SetComponent<IGrainStateAccessor<int>>(accessor);

    return base.OnActivateAsync();
}

在上述範例中,您會建立 GrainStateAccessor<int> 的新執行個體,以取得整數狀態值的 gettersettergetter 會讀取目標粒紋的 Value 屬性,而 setter 則會設定 Value 屬性的新值。 接著,您可以使用 IGrainContext.SetComponent 方法,將此執行個體設定為目標粒紋內容的元件。

註冊延伸模組之後,您可以透過延伸模組的參考來取得並設定目標粒紋的狀態。

// Get a reference to the IGrainStateAccessor<int> extension
var accessor = grain.AsReference<IGrainStateAccessor<int>>();

// Get the current value of the state
var value = await accessor.GetState();

// Set a new value of the state
await accessor.SetState(10);

在上述範例中,您會使用 GrainExtensions.AsReference 方法來取得特定粒紋執行個體 IGrainStateAccessor<int> 延伸模組的參考。 然後,您可以使用這個參考來呼叫 GetState()SetState(T state) 方法,以讀取及修改目標粒紋的狀態值。

另請參閱