Partilhar via


Extensões de grãos

As extensões de grãos fornecem uma maneira de adicionar funcionalidades adicionais aos grãos. Ao estender um grão com uma interface derivada de IGrainExtension, novos métodos e funcionalidades podem ser adicionados ao grão.

Este artigo apresenta dois exemplos de expansão de grãos. O primeiro exemplo mostra como adicionar um Deactivate método a todos os grãos, utilizável para desativar o grão. O segundo exemplo mostra como adicionar GetState e SetState métodos a qualquer grão, permitindo a manipulação do estado interno do grão.

Desativar exemplo de extensão

Este exemplo demonstra a adição automática de um Deactivate método a todos os grãos. Use o método para desativar o grão; ele aceita uma cadeia de caracteres como um parâmetro de mensagem. Orleans Os grãos já suportam esta funcionalidade através da IGrainManagementExtension interface. No entanto, este exemplo mostra como esta funcionalidade ou semelhante pode ser adicionada.

Desativar interface de extensão

Comece definindo uma IGrainDeactivateExtension interface contendo o Deactivate método. A interface deve derivar de IGrainExtension.

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

Desativar a implementação da extensão

Em seguida, implemente a GrainDeactivateExtension classe, fornecendo a implementação para o Deactivate método.

Para acessar o grão de destino, recupere o IGrainContext do construtor. É injetado através da injeção de dependência ao criar a extensão.

public sealed class GrainDeactivateExtension : IGrainDeactivateExtension
{
    private IGrainContext _context;

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

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

Desativar o registro e o uso da extensão

Agora que a interface e a implementação estão definidas, registre a extensão ao configurar o silo usando o AddGrainExtension método.

siloBuilder.AddGrainExtension<IGrainDeactivateExtension, GrainDeactivateExtension>();

Para usar a extensão em qualquer grão, recupere uma referência à extensão e chame seu Deactivate método.

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

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

Exemplo de extensão de manipulação de estado

Este exemplo demonstra a adição GetState e SetState métodos a qualquer grão através de extensões, permitindo a manipulação do estado interno do grão.

Interface de extensão de manipulação de estado

Primeiro, defina a IGrainStateAccessor<T> interface que contém os GetState métodos e SetState . Novamente, essa interface deve derivar de IGrainExtension.

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

Quando o acesso ao grão alvo estiver disponível, use a extensão para manipular seu estado. Neste exemplo, use uma extensão para acessar e modificar um valor de estado inteiro específico dentro do grão de destino.

Implementação da extensão para manipulação de estado

A extensão usada é IGrainStateAccessor<T>, fornecendo métodos para obter e definir um valor de estado do tipo T. Para criar a extensão, implemente a interface em uma classe tomando a getter e a setter como argumentos em seu construtor.

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;
    }
}

Na implementação anterior, a GrainStateAccessor<T> classe toma getter e setter argumentos no seu construtor. Esses delegados leem e modificam o estado do grão alvo. GetState() método retorna um Task<TResult> que encapsula o valor atual do estado T, enquanto SetState(T state) método atualiza o valor do estado T para o novo valor.

Registo e utilização da extensão de manipulação de estado

Para usar a extensão para acessar e modificar o estado do grão alvo, registre a extensão e defina seus componentes no método do Grain.OnActivateAsync() grão alvo.

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();
}

No exemplo anterior, crie uma nova instância de GrainStateAccessor<int> utilizando um getter e um setter para um valor de estado inteiro. O getter lê a Value propriedade do grão de destino, enquanto o setter define o novo valor da Value propriedade. Em seguida, defina essa instância como um componente do contexto do grão de destino usando o IGrainContext.SetComponent método.

Uma vez que a extensão é registrada, use-a para obter e definir o estado do grão de destino acessando-o através de uma referência à extensão.

// 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);

No exemplo anterior, obtenha uma referência à extensão IGrainStateAccessor<int> para uma instância específica do grain usando o método GrainExtensions.AsReference. Em seguida, use essa referência para chamar os métodos GetState() e SetState(T state) para ler e modificar o valor de estado do grão de destino.

Ver também