考慮以下幾點:Autofac - 註冊多個裝飾
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");
}
}
我可以使用下面的代碼裝飾MoveCustomerCommandHandler
用TransactionCommandHandlerDecorator
:
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());
將輸出:
TransactionCommandHandlerDecorator - before
MoveCustomerCommandHandler
TransactionCommandHandlerDecorator - after
我怎樣才能用裝飾,生成以下輸出
DeadlockRetryCommandHandlerDecorator- before
TransactionCommandHandlerDecorator - before
MoveCustomerCommandHandler
TransactionCommandHandlerDecorator - after
DeadlockRetryCommandHandlerDecorator- after
附加問題加分:你如何在Autofac中註冊一個有條件的裝飾器,例如基於泛型約束? – Steven
@Steven很好的問題,我不知道:)這是我第一次使用Autofac中的裝飾器功能來回答這個問題,所以我必須查看它,但我想默認的實現並不是那麼靈活提供條件,但你總是可以編寫你自己的'IRegistrationSource' ...但我想在SimpleInjector中有很簡單的方法來做到這一點;) – nemesv
我這樣問,因爲我經常從想要應用這些模式的開發者那裏得到問題使用其他容器,而不是簡單的注射器,但不幸的是我無法給他們提供很好的答案 - 除了使用簡單注射器的建議:-)。但是,你是對的,這是一個簡單的噴油器真正發光的區域。 – Steven