Autofac – 注册多个装饰器

鉴于以下内容:

public interface ICommandHandler { void Handle(TCommand command); } public class MoveCustomerCommand { } public class MoveCustomerCommandHandler : ICommandHandler { public void Handle(MoveCustomerCommand command) { Console.WriteLine("MoveCustomerCommandHandler"); } } public class TransactionCommandHandlerDecorator : ICommandHandler { private readonly ICommandHandler _decorated; public TransactionCommandHandlerDecorator(ICommandHandler decorated) { _decorated = decorated; } public void Handle(TCommand command) { Console.WriteLine("TransactionCommandHandlerDecorator - before"); _decorated.Handle(command); Console.WriteLine("TransactionCommandHandlerDecorator - after"); } } public class DeadlockRetryCommandHandlerDecorator : ICommandHandler { private readonly ICommandHandler _decorated; public DeadlockRetryCommandHandlerDecorator(ICommandHandler decorated) { _decorated = decorated; } public void Handle(TCommand command) { Console.WriteLine("DeadlockRetryCommandHandlerDecorator - before"); _decorated.Handle(command); Console.WriteLine("DeadlockRetryCommandHandlerDecorator - after"); } } 

我可以使用以下代码使用TransactionCommandHandlerDecorator修饰MoveCustomerCommandHandler

 var builder = new ContainerBuilder(); builder.RegisterAssemblyTypes(typeof(MoveCustomerCommandHandler).Assembly) .As(type => type.GetInterfaces() .Where(interfaceType => interfaceType.IsClosedTypeOf(typeof(ICommandHandler))) .Select(interfaceType => new KeyedService("commandHandler", interfaceType))); builder.RegisterGenericDecorator( typeof(TransactionCommandHandlerDecorator), typeof(ICommandHandler), fromKey: "commandHandler"); var container = builder.Build(); var commandHandler = container.Resolve<ICommandHandler>(); commandHandler.Handle(new MoveCustomerCommand()); 

哪个会输出:

 TransactionCommandHandlerDecorator - before MoveCustomerCommandHandler TransactionCommandHandlerDecorator - after 

如何使用DeadlockRetryCommandHandlerDecorator装饰TransactionCommandHandlerDecorator ,以生成以下输出

 DeadlockRetryCommandHandlerDecorator- before TransactionCommandHandlerDecorator - before MoveCustomerCommandHandler TransactionCommandHandlerDecorator - after DeadlockRetryCommandHandlerDecorator- after 

您只需将“TransactionCommandHandlerDecoratored” ICommandHandler注册为Keyed服务,并在注册第二个DeadlockRetryCommandHandlerDecorator时使用该新密钥:

 builder.RegisterGenericDecorator( typeof(TransactionCommandHandlerDecorator<>), typeof(ICommandHandler<>), fromKey: "commandHandler") .Keyed("decorated", typeof(ICommandHandler<>)); builder.RegisterGenericDecorator( typeof(DeadlockRetryCommandHandlerDecorator<>), typeof(ICommandHandler<>), fromKey: "decorated"); 

您将获得以下输出:

 DeadlockRetryCommandHandlerDecorator - before TransactionCommandHandlerDecorator - before MoveCustomerCommandHandler TransactionCommandHandlerDecorator - after DeadlockRetryCommandHandlerDecorator - after 

@nemesv已经回答了这个问题,但是我只是想我会补充一点,你可以添加一些简单的帮助方法来使很多通用装饰器连接起来,减少Autofac的痛苦:

  private static void RegisterHandlers( ContainerBuilder builder, Type handlerType, params Type[] decorators) { RegisterHandlers(builder, handlerType); for (int i = 0; i < decorators.Length; i++) { RegisterGenericDecorator( builder, decorators[i], handlerType, i == 0 ? handlerType : decorators[i - 1], i != decorators.Length - 1); } } private static void RegisterHandlers(ContainerBuilder builder, Type handlerType) { builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .As(t => t.GetInterfaces() .Where(v => v.IsClosedTypeOf(handlerType)) .Select(v => new KeyedService(handlerType.Name, v))) .InstancePerRequest(); } private static void RegisterGenericDecorator( ContainerBuilder builder, Type decoratorType, Type decoratedServiceType, Type fromKeyType, bool hasKey) { var result = builder.RegisterGenericDecorator( decoratorType, decoratedServiceType, fromKeyType.Name); if (hasKey) { result.Keyed(decoratorType.Name, decoratedServiceType); } } 

如果将这些方法粘贴到您正在配置Autofac的位置,那么您可以这样做:

  RegisterHandlers( builder, typeof(ICommandHandler<>), typeof(TransactionCommandHandlerDecorator<>), typeof(ValidationCommandHandlerDecorator<>)); 

它将连接所有命令处理程序并按给定的顺序添加装饰器。