我正在使用基于此Link的CQRS并使用SimpleInjector来启动我的装饰器。但他们没有被解雇。我在这里做错了吗?
这是我的 ICommandHandler 部分:
public interface ICommandHandler<TCommand> where TCommand : Command
{
void Handle(TCommand command);
}
public interface ICommandHandler<TCommand, TResult> : ICommandHandler<TCommand>
where TCommand : Command<TResult>
{
}
BaseCommandHandler 部分:
public abstract class BaseCommandHandler<TCommand>
: ICommandHandler<TCommand> where TCommand : Command
{
public DbEntities Db { get; set; }
public BaseCommandHandler(DbEntities db)
{
Db = db;
}
public BaseCommandHandler() : this(new DbEntities())
{
}
public abstract void Handle(TCommand command);
}
public abstract class BaseCommandHandler<TCommand, TResult>
: BaseCommandHandler<TCommand>
where TCommand : Command<TResult>
{
}
SimpleInjector配置:
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
typeof(BaseCommandHandler<>).Assembly);
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(LoggerCommandHandlerDecorator<Command>));
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(ValidationCommandHandlerDecorator<Command>));
注意:ICommandHandler和BaseCommandHandler都驻留在不同的库程序集中。这是有目的的。
任何帮助将不胜感激!
答案 0 :(得分:2)
您注册了两个封闭式通用装饰器,而不是开放式通用类型。这是您的注册:
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(LoggerCommandHandlerDecorator<Command>));
此配置所说的是,对于已解决的每个ICommandHandler<T>
实现,尽可能尝试用LoggerCommandHandlerDecorator<Command>
包装它。但是,由于您提供了已关闭的LoggerCommandHandlerDecorator<Command>
,因此它只能应用于ICommandHandler<Command>
实现,但不能应用于任何子类型的命令,例如ICommandHandler<MoveCustomerCommand>
。
这是不可能的原因,因为当有人请求ICommandHandler<MoveCustomerCommand>
时,它会期望此类型的实现,但LoggerCommandHandlerDecorator<Command>
未实现ICommandHandler<MoveCustomerCommand>
;它只实现ICommandHandler<Command>
。因此,虽然LoggerCommandHandlerDecorator<Command>
可以包裹ICommandHandler<MoveCustomerCommand>
,但它无法返回。这会导致InvalidCastException
。
所以这应该是你的注册:
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(LoggerCommandHandlerDecorator<>));