Abbiamo molti gestori di comandi generici registrati da Autofac in modo generico aperto. Abbiamo un paio di decoratori che decorano tutte le maniglie. Ora ho bisogno di registrare un decoratore per un solo gestore di comandi e non influire su tutti gli altri gestori di comandi. Ecco il mio tentativo, ma non sembra che abbia ottenuto la registrazione giusta.Registrati Decoratore Autofac per un solo gestore di comandi generici
è semplice codice di prova che è simile al nostro codice:
Abbiamo centinaia di comandi che lavorano in questo modo:
class NormalCommand : ICommand { }
// This command handler should not be decorated
class NormalCommandHandler : ICommandHandler<NormalCommand>
{
public void Handle(NormalCommand command) { }
}
E vorrei avvolgere SOLO TestCommandHandler
in decoratore TestCommandHandlerDecorator
class TestCommand : ICommand { }
// And I would like to put decorator around this handler
class TestCommandHandler : ICommandHandler<TestCommand>
{
public void Handle(TestCommand command) { }
}
// This decorator should be wrapped only around TestCommandHandler
class TestCommandHandlerDecorator : ICommandHandler<TestCommand>
{
private readonly ICommandHandler<TestCommand> decorated;
public TestCommandHandlerDecorator(ICommandHandler<TestCommand> decorated)
{
this.decorated = decorated;
}
public void Handle(TestCommand command)
{
// do something
decorated.Handle(command);
// do something again
}
}
Ecco come registro i miei componenti:
static class AutofacRegistration
{
public static IContainer RegisterHandlers()
{
var builder = new ContainerBuilder();
//Register All Command Handlers but not decorators
builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(AutofacRegistration)))
.Where(t => !t.Name.EndsWith("Decorator"))
.AsClosedTypesOf(typeof(ICommandHandler<>))
.InstancePerLifetimeScope();
// and here is the battle!
builder.RegisterType<TestCommandHandler>()
.Named<ICommandHandler<TestCommand>>("TestHandler")
.InstancePerLifetimeScope();
// this does not seem to wrap the decorator
builder.RegisterDecorator<ICommandHandler<TestCommand>>(
(c, inner) => new TestCommandHandlerDecorator(inner),
fromKey: "TestHandler")
.Named<ICommandHandler<TestCommand>>("TestHandler1")
.InstancePerLifetimeScope();
return builder.Build();
}
}
Ed è così che provo a confermare che ricevo corrette istanze di gestori di comando/decoratori:
class AutofacRegistrationTests
{
[Test]
public void ResolveNormalCommand()
{
var container = AutofacRegistration.RegisterHandlers();
var result = container.Resolve<ICommandHandler<NormalCommand>>();
// this resolves correctly
Assert.IsInstanceOf<NormalCommandHandler>(result); // pass
}
[Test]
public void TestCommand_Resolves_AsDecorated()
{
var container = AutofacRegistration.RegisterHandlers();
var result = container.Resolve<ICommandHandler<TestCommand>>();
// and this resolves to TestCommandHandler, not decorated!
Assert.IsInstanceOf<TestCommandHandlerDecorator>(result); // FAILS!
}
}
Come il commento dice, decoratore non è sempre applicata, la registrazione decoratore viene ignorata.
Qualsiasi idi come registrare questo decoratore ?? Che cosa sto facendo di sbagliato?
Posso fornire una soluzione che utilizza un altro contenitore DI o sei collegato ad Autofac? – Steven
Al momento sono collegato ad Autofac, ma se riesci a fornire degli esempi in Structure Map o Windsor, sarò interessato anche a guardarlo. Per scopi educativi. – trailmax