3

如何註冊條件修飾符 in SimpleInjector?這裏是我的定義:在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 
    ); 

回答

5

可以使用RegisterDecorator重載需要一個DecoratorPredicateContext來定義您的修飾器應該應用的條件。但是,因爲在你的情況下,條件只是泛型類型約束,所以你不必提供謂詞。當給定服務類型不可裝飾時,簡單注入器將自動忽略裝飾器,並且這包括通用類型約束。

換句話說,只要註冊您的裝飾如下所示,將正常工作:

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

真的嗎?!它非常好,很有用。謝謝。歡呼 –

2

看來我可以用DecoratorPredicateContext.ServiceType

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

@Steven謝謝你這麼多。我知道了 –