如何使用SimpleInjector将条件装饰器应用于命令处理程序?

时间:2016-02-04 10:51:23

标签: c# .net simple-injector

我有以下命令处理程序接口:

int regcomp(regex_t *preg, const char *regex, int cflags); 
int regexec(const regex_t *preg, const char *string, size_t nmatch, 
        regmatch_t pmatch[], int eflags); 

我正在使用以下具体类来装饰此接口的实例:

public interface ICommandHandler<TCommand> where TCommand : ICommand
{
    void Handle(TCommand command);
}

但是......我不一定要装饰所有命令处理程序,只想装饰public class ValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> where TCommand : ICommand { public ValidationCommandHandlerDecorator( IValidator<TCommand> validator, ICommandHandler<TCommand> handler) { } public void Handle(TCommand command) { } } IF实例存在/注册ICommandHandler<TCommand>以获取具体类型的TCommand。请注意,IValidator<TCommand>实例是在装饰器类的构造函数中注入的。

例如,如果我有一个命令处理程序:

IValidator<TCommand>

如果我注册了以下实例,我只想装饰:

public class CreateFooCommandHandler : ICommandHandler<CreateFooCommand>

如果public class CreateFooCommandValidator : IValidator<CreateFooCommand> 不存在,那么我不想用CreateFooCommandValidator装饰CreateFooCommandHandler

我在使用SimpleInjector注册时使用以下内容:

ValidationCommandHandlerDecorator

如果任何给定的var container = new Container(); container.Register(typeof(ICommandHandler<>), assemblies); container.Register(typeof(IValidator<>), assemblies); container.RegisterDecorator( typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>)); 没有IValidator<>的实例,显然会失败。对于信息ICommandHandler<>是用于注册泛型类的程序集的集合。

如果可能的话,我应该使用什么来注册装饰器/验证器以实现我想要做的事情?我不想从使用SimpleInjector切换。

此外,如果可能,这是推荐还是违反SOLID原则,甚至只是代码味?

1 个答案:

答案 0 :(得分:1)

您可以通过分析容器中的注册并决定是否装饰每个实例来注册条件装饰器,但我不认为它是最佳选择。最简单的解决方案是为实际NullValidator不存在的实例定义并注册回退IValidator ...

public class NullValidator<TCommand> : IValidator<TCommand> where TCommand : ICommand
{
    public void Validate(TCommand command)
    {
    }
}

注册为条件

var container = new Container();

container.Register(typeof(ICommandHandler<>), assemblies);
container.Register(typeof(IValidator<>), assemblies);
container.RegisterConditional(
    typeof(IValidator<>), 
    typeof(NullValidator<>), 
    c => !c.Handled);
container.RegisterDecorator(
    typeof(ICommandHandler<>), 
    typeof(ValidationCommandHandlerDecorator<>));

container.Verify();
  

我不想使用SimpleInjector切换。

好人!

  

此外,如果可能,这是推荐还是违反SOLID原则,甚至只是代码味?

这正是RegisterConditional存在的事情: - )