如何使用Ninject绑定修饰的命令处理程序类

时间:2015-03-31 13:36:37

标签: c# domain-driven-design ninject cqrs

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

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 对象执行的。

1 个答案:

答案 0 :(得分:1)

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

但是,您可以使用contextual bindings来实现装饰:

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

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

而不是.When(..)重载.WhenInjectedInto(typeof(PostCommitCOmmandHandlerDecorator<>))也可能有效,但我怀疑它不会。