如何将修饰的命令处理程序类与Ninject绑定



我有一个命令处理程序接口类型,

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

实现的命令处理程序由命令调度对象执行。

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

我通过ninject绑定命令处理程序类,如下所示:

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

这是有效的。

但我需要命令处理程序装饰器,例如验证:

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

我如何用这样的装饰器来装饰我的命令处理程序类?我应该将它绑定到Ninject内核吗?因为我的命令是由ICommandDispatches对象执行的。

开箱即用的Ninject不支持装饰器配置。

但是,您可以使用上下文绑定来实现装饰:

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

.When(..)过载不同,.WhenInjectedInto(typeof(PostCommitCOmmandHandlerDecorator<>))也可以工作,但我怀疑它不会。

最新更新