SimpleInjector - 装饰器没有启动?

时间:2014-03-31 14:16:48

标签: asp.net-mvc dependency-injection cqrs simple-injector

我正在使用基于此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都驻留在不同的库程序集中。这是有目的的。

任何帮助将不胜感激!

1 个答案:

答案 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<>));