我在我的应用程序中实现了 CQRS 方法,深受这篇精彩文章的影响:https ://cuttingedge.it/blogs/steven/pivot/entry.php?id=9 。我的命令和处理程序代码的设置与文章相同,并且该部分运行良好。当我尝试实现一个装饰器类来处理命令的验证时,我的问题就出现了。简单的命令处理界面如下所示:
public interface ICommand
{
}
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
然后对于验证装饰器,我有:
public class ValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> where TCommand : CommandBase
{
private readonly ICommandHandler<TCommand> _decoratedCommandHandler;
private readonly ICommandValidator<TCommand> _commandValidator;
public ValidationCommandHandlerDecorator(ICommandHandler<TCommand> decoratedCommandHandler, ICommandValidator<TCommand> commandValidator)
{
_decoratedCommandHandler = decoratedCommandHandler;
_commandValidator = commandValidator;
}
public void Handle(TCommand command)
{
if (_commandValidator != null)
{
var validationResult = _commandValidator.Validate(command);
if (validationResult != null)
{
command.Success = false;
command.Errors = validationResult;
return;
}
}
_decoratedCommandHandler.Handle(command);
command.Success = true;
}
}
它使用接口来定义验证器:
public interface ICommandValidator<TCommand>
{
IEnumerable<string> Validate(TCommand command);
}
AndCommandBase是一个简单的基类,它允许我存储命令的成功或失败以及失败时发生的错误。我更喜欢这种方法来替代抛出异常。所有命令都将继承这个基类。
public abstract class CommandBase : ICommand
{
public bool Success { get; set; }
public IEnumerable<string> Errors { get; set; }
}
这一切都连接到结构映射注册表中的 IoC 容器:
public class CommandRegistry : Registry
{
public CommandRegistry()
{
Scan(s =>
{
s.AssemblyContainingType<CommandBase>();
s.ConnectImplementationsToTypesClosing(typeof(ICommandHandler<>));
s.ConnectImplementationsToTypesClosing(typeof(ICommandValidator<>));
s.WithDefaultConventions();
For(typeof(ICommandHandler<>)).DecorateAllWith(typeof(ValidationCommandHandlerDecorator<>));
});
}
}
现在,由于我为每个 ICommandHandler 注册了该装饰器,如果我有一个不需要验证器且未定义验证器的命令,则无法找到该类的ICommandValidator<TCommand> _commandValidator私有字段,ValidationCommandHandlerDecorator<TCommand>因为它当然不存在并且将总是抛出以下结构映射错误:
“没有注册默认实例,无法自动确定类型‘ICommandValidator’没有为 ICommandValidator 指定配置”
结构映射中是否有一种方法来定义如何ValidationCommandHandlerDecorator构造,以便在不存在时使用某种类型的默认验证器,而不必依赖类中的容器或必须创建一个IValidateableCommandHandler<TCommand>接口来处理命令验证者?
谢谢你。