我有一个命令处理程序接口类型,
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 对象执行的。
答案 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<>))
也可能有效,但我怀疑它不会。