条件注册基于SimpleInjector中的泛型类型约束的命令装饰器

时间:2012-10-07 01:29:43

标签: .net dependency-injection inversion-of-control decorator simple-injector

如何在SimpleInjector中注册条件装饰器?以下是我的定义:

public interface ICommand { }

public interface ICleanableCommand : ICommand {
    void Clean();
}

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

public class CleanableCommandHandlerDecorator<TCommand> 
    : ICommandHandler<TCommand> 
    where TCommand : ICleanableCommand {

    private readonly ICommandHandler<TCommand> _handler;

    public CleanableCommandHandlerDecorator(
        ICommandHandler<TCommand> handler) {
        _handler = handler;
    }

    void ICommandHandler<TCommand>.Handle(TCommand command) {
        command.Clean();
        _handler.Handle(command);
    }
}

我正在努力:

container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>),
    AppDomain.CurrentDomain.GetAssemblies()
    );

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(CleanableCommandHandlerDecorator<>)
    // ,context => context.ImplementationType ???
    // I want to register this decorator for commandhandlers 
    // which their command implements ICleanableCommand 
    );

2 个答案:

答案 0 :(得分:5)

您可以使用RegisterDecorator重载来DecoratorPredicateContext来定义应用装饰器的条件。但是,因为在您的情况下,条件只是泛型类型约束,所以您不必提供谓词。当给定的服务类型不可解析时,Simple Injector将自动忽略装饰器,这包括泛型类型约束。

换句话说,只需按照以下方式注册装饰器,它就能正常工作:

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(CleanableCommandHandlerDecorator<>));

答案 1 :(得分:2)

我似乎可以使用 DecoratorPredicateContext.ServiceType

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(CleanableCommandHandlerDecorator<>),
    context => {
        var genArg = context.ServiceType.GetGenericArguments()[0];
        return typeof(ICleanableCommand).IsAssignableFrom(genArg);
    });