Autofac - Register multiple decorators

autofac, c#, dependency-injection

Solution

You just need to register your "TransactionCommandHandlerDecoratored" `ICommandHandler` as a `Keyed` service and use that new key when registering your second `DeadlockRetryCommandHandlerDecorator`:

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

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

And you will get the following output:

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

Problem

Given the following: ``` public interface ICommandHandler<in TCommand> { void Handle(TCommand command); } public class MoveCustomerCommand { } public class MoveCustomerCommandHandler : ICommandHandler<MoveCustomerCommand> { public void Handle(MoveCustomerCommand command) { Console.WriteLine("MoveCustomerCommandHandler"); } } public class TransactionCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> { private readonly ICommandHandler<TCommand> _decorated; public TransactionCommandHandlerDecorator(ICommandHandler<TCommand> decorated) { _decorated = decorated; } public void Handle(TCommand command) { Console.WriteLine("TransactionCommandHandlerDecorator - before"); _decorated.Handle(command); Console.WriteLine("TransactionCommandHandlerDecorator - after"); } } public class DeadlockRetryCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> { private readonly ICommandHandler<TCommand> _decorated; public DeadlockRetryCommandHandlerDecorator(ICommandHandler<TCommand> decorated) { _decorated = decorated; } public void Handle(TCommand command) { Console.WriteLine("DeadlockRetryCommandHandlerDecorator - before"); _decorated.Handle(command); Console.WriteLine("DeadlockRetryCommandHandlerDecorator - after"); } } ``` I can decorate the `MoveCustomerCommandHandler` with a `TransactionCommandHandlerDecorator` using the following code: ``` 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<MoveCustomerCommand>>(); commandHandler.Handle(new MoveCustomerCommand()); ``` Which will output : ``` TransactionCommandHandlerDecorator - before MoveCustomerCommandHandler TransactionCommandHandlerDecorator - after ``` How can I also decorate the `TransactionCommandHandlerDecorator` with the `DeadlockRetryCommandHandlerDecorator`, to generate the following output ``` DeadlockRetryCommandHandlerDecorator- before TransactionCommandHandlerDecorator - before MoveCustomerCommandHandler TransactionCommandHandlerDecorator - after DeadlockRetryCommandHandlerDecorator- after ```

Original source