2015-03-31 1 views
0

J'ai un type de gestionnaire de commandes interface,Comment lier des classes décorées de gestionnaire de commande avec Ninject

public interface ICommandHandler<in TCommand> 
{ 
    void Handle(TCommand command); 
} 

mis en œuvre gestionnaires de commandes exécutent par commande expédiée objet.

public class CommandDispacher : ICommandDispatcher 
{ 
    private readonly IServiceLocator serviceLocator; 

    public CommandDispacher(IServiceLocator serviceLocator) 
    { 
     this.serviceLocator = serviceLocator; 
    } 

    public void Dispatch<TCommand>(ICommand command) 
    { 
     var commandType = typeof(ICommandHandler<>).MakeGenericType(command.GetType()); 
     var handler = serviceLocator.Resolve(commandType); 

     ((dynamic)handler).Handle((dynamic)command); 
    } 
} 

Je suis liant les classes de gestionnaire de commandes par ninject comme ceci:

  Kernel.Bind(scanner =>  
      scanner.FromAssembliesMatching("*") 
      .IncludingNonePublicTypes() 
      .SelectAllClasses() 
      .InheritedFrom(typeof(ICommandHandler<>)) 
      .BindSingleInterface()); 

Cela fonctionne.

Mais je dois commander les décorateurs de gestionnaire, par exemple les validations:

public class PostCommitCommandHandlerDecorator<T> : ICommandHandler<T> where T:ICommand 
{ 
    private readonly ICommandHandler<T> decorated; 
    private readonly PostCommitRegistratorImpl registrator; 

    public PostCommitCommandHandlerDecorator(ICommandHandler<T> decorated, PostCommitRegistratorImpl registrator) 
    { 
     this.decorated = decorated; 
     this.registrator = registrator; 
    } 

    public void Handle(T command) 
    { 
     try 
     { 
      decorated.Handle(command); 

      registrator.ExecuteActions(); 
     } 
     catch (Exception) 
     { 
      registrator.Reset(); 
     } 
    } 
} 

Comment puis-je décorer mes classes de traitement de commandes avec des décorateurs avec cela comme? Devrais-je le lier au noyau Ninject? Parce que mes commandes sont exécutées par l'objet ICommandDispatches . Sortie de la boîte Ninject ne prend pas en charge une configuration de décorateur.

Répondre

1

Cependant, vous pouvez utiliser contextual bindings pour réaliser la décoration:

Bind(typeof(ICommandHandler<>)) 
    .To(typeof(PostCommitCommandHandlerDecorator<>)); 

Bind(typeof(ICommandHandler<>)) 
    .To(typeof(CommandHandler<>)) 
    .When(request => 
    request.Target.Type.GetGenericTypeDefinition() 
    == typeof(PostCommitCommandHandlerDecorator<>)); 

Au lieu de la .When(..) surcharge .WhenInjectedInto(typeof(PostCommitCOmmandHandlerDecorator<>)) pourrait fonctionner aussi bien, mais je pense que ce ne sera pas.