Extensions de grain
Les extensions de grain permettent d’ajouter un comportement supplémentaire aux grains. En étendant un grain avec une interface qui dérive de IGrainExtension, vous pouvez ajouter de nouvelles méthodes et fonctionnalités au grain.
Dans cet article, vous voyez deux exemples d’extensions de grain. Le premier exemple montre comment ajouter une méthode Deactivate
à tous les grains qui peuvent être utilisés pour désactiver le grain. Le deuxième exemple montre comment ajouter une méthode GetState
et SetState
à n’importe quel grain, ce qui vous permet de manipuler l’état interne du grain.
Exemple d’extension de désactivation
Dans cet exemple, vous allez apprendre à ajouter automatiquement une méthode Deactivate
à tous les grains. La méthode peut être utilisée pour désactiver le grain et accepte une chaîne en tant que paramètre de message. Les grains Orleans prennent déjà en charge cette fonctionnalité via l’interface IGrainManagementExtension. Néanmoins, cet exemple montre comment vous pouvez ajouter vous-même cette fonctionnalité ou une fonctionnalité similaire.
Désactivez l’interface d’extension
Commencez par définir une interface IGrainDeactivateExtension
qui contient la méthode Deactivate
. L’interface doit dériver de IGrainExtension
.
public interface IGrainDeactivateExtension : IGrainExtension
{
Task Deactivate(string msg);
}
Désactivez l’implémentation de l’extension
Ensuite, implémentez la classe GrainDeactivateExtension
, qui fournit l’implémentation de la méthode Deactivate
.
Pour accéder au grain cible, vous récupérez le IGrainContext
à partir du constructeur. Il est injecté lors de la création de l’extension avec l’injection de dépendances.
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;
}
}
Désactivez l’inscription et l’utilisation de l’extension
Maintenant que vous avez défini l’interface et l’implémentation, vous inscrivez l’extension lors de la configuration du silo avec la méthode AddGrainExtension.
siloBuilder.AddGrainExtension<IGrainDeactivateExtension, GrainDeactivateExtension>();
Pour utiliser l’extension sur n’importe quel grain, récupérez une référence à l’extension et appelez la méthode Deactivate
.
var grain = client.GetGrain<SomeExampleGrain>(someKey);
var grainReferenceAsInterface = grain.AsReference<IGrainDeactivateExtension>();
await grainReferenceAsInterface.Deactivate("Because, I said so...");
Exemple d’extension de manipulation d’état
Dans cet exemple, vous allez apprendre à ajouter une méthode GetState
et SetState
à n’importe quel grain via des extensions, ce qui vous permet de manipuler l’état interne du grain.
Interface d’extension de manipulation d’état
Tout d’abord, définissez l’interface IGrainStateAccessor<T>
, qui contient les méthodes GetState
et SetState
. Là encore, cette interface doit dériver de IGrainExtension
.
public interface IGrainStateAccessor<T> : IGrainExtension
{
Task<T> GetState();
Task SetState(T state);
}
Une fois que vous avez accès au grain cible, vous pouvez utiliser l’extension pour manipuler son état. Dans cet exemple, vous utilisez une extension pour accéder et modifier une valeur d’état entière spécifique dans le grain cible.
Implémentation de l’extension de manipulation d’état
L’extension que vous utilisez est IGrainStateAccessor<T>
, qui fournit des méthodes pour obtenir et définir une valeur d’état de type T
. Pour créer l’extension, vous implémentez l’interface dans une classe qui prend un getter
et un setter
comme arguments dans son constructeur.
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;
}
}
Dans l’implémentation précédente, la classe GrainStateAccessor<T>
prend des arguments getter
et setter
dans son constructeur. Ces délégués sont utilisés pour lire et modifier l’état du grain cible. La méthode GetState()
renvoie un Task<TResult> enveloppant la valeur actuelle de l’état T
, tandis que la méthode SetState(T state)
définit la nouvelle valeur de l’état T
.
Inscription et utilisation de l’extension de manipulation d’état
Pour utiliser l’extension afin d’accéder et de modifier l’état du grain cible, vous devez inscrire l’extension et définir ses composants dans la méthode Grain.OnActivateAsync() du grain cible.
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();
}
Dans l’exemple précédent, vous créez une nouvelle instance de GrainStateAccessor<int>
qui prend un getter
et un setter
pour une valeur d’état entière. Le getter
lit la propriété Value
du grain cible, tandis que le setter
définit la nouvelle valeur de la propriété Value
. vous définissez ensuite cette instance en tant que composant du contexte du grain cible à l’aide de la méthode IGrainContext.SetComponent.
Une fois l’extension inscrite, vous pouvez l’utiliser pour obtenir et définir l’état du grain cible en y accédant via une référence à l’extension.
// 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);
Dans l’exemple précédent, vous obtenez une référence à l’extension IGrainStateAccessor<int>
pour une instance de grain spécifique à l’aide de la méthode GrainExtensions.AsReference. vous pouvez ensuite utiliser cette référence pour appeler les méthodes GetState()
et SetState(T state)
afin de lire et de modifier la valeur d’état du grain cible.