How to register a conditional decorator in SimpleInjector? Here are my definitions:

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);
    }
}

And I'm trying:

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 
    );
有帮助吗?

解决方案

You can use the RegisterDecorator overload that takes an DecoratorPredicateContext to define the condition under which your decorator should be applied. However, since in your case the condition is just the generic type constraint, you don't have to supply a predicate. Simple Injector will automatically ignore the decorator when the given service type is not decoratable, and this includes generic type constraints.

In other words, just register your decorator as follows and it will work correctly:

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

其他提示

It seems I can use DecoratorPredicateContext.ServiceType:

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(CleanableCommandHandlerDecorator<>),
    context => {
        var genArg = context.ServiceType.GetGenericArguments()[0];
        return typeof(ICleanableCommand).IsAssignableFrom(genArg);
    });
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top