Wir haben eine Menge generische Befehlshandler, die von Autofac in Open-Generic Mode registriert sind. Wir haben Paardekorateure, die alle Griffe schmücken. Jetzt muss ich einen Decorator für nur einen Befehlshandler registrieren und nicht alle anderen Befehlshandler beeinflussen. Hier ist mein Versuch, aber ich glaube nicht, dass die Registrierung richtig ist.Registrierung Autofac Dekorator für nur einen generischen Befehl Handler
ist hier einfacher Test-Code, der in unseren Code ähnlich ist:
Wir hunderte von Befehlen haben wie diese Arbeit:
class NormalCommand : ICommand { }
// This command handler should not be decorated
class NormalCommandHandler : ICommandHandler<NormalCommand>
{
public void Handle(NormalCommand command) { }
}
Und ich möchte wickeln NUR TestCommandHandler
in Dekorateur 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
}
}
So registriere ich meine Komponenten:
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();
}
}
Und das ist, wie ich versuche, zu bestätigen, dass ich richtig Instanzen von Befehlshandler/Dekorateure erhalten:
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!
}
}
Wie der Kommentar sagt, ist Dekorateur nicht angewandt zu werden, Dekorateur Registrierung ignoriert.
Irgendwelche Informationen, wie Sie diesen Dekorateur registrieren? Was mache ich falsch?
Darf ich bieten eine Lösung unter Verwendung eines anderen DI-Container oder sind Sie mit Autofac verbunden? – Steven
Ich bin gerade mit Autofac verbunden, aber wenn Sie Beispiele in Structure Map oder Windsor angeben können, werde ich mich auch darum kümmern. Für Bildungszwecke. – trailmax