我们有很多由 Autofac 以开放通用方式注册的通用命令处理程序。我们有几个装饰器来装饰所有把手。现在我只需要为一个命令处理程序注册一个装饰器,而不影响所有其他命令处理程序。这是我的尝试,但我似乎没有正确注册。
这是与我们的代码类似的简单测试代码:
我们有数百个命令是这样工作的:
class NormalCommand : ICommand { }
// This command handler should not be decorated
class NormalCommandHandler : ICommandHandler<NormalCommand>
{
    public void Handle(NormalCommand command) { }
}
我只想TestCommandHandler用装饰器包装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
    }
}
这就是我注册组件的方式:
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();
    }
}
这就是我尝试确认我得到正确的命令处理程序/装饰器实例的方式:
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!
    }
}
正如评论所说,装饰器没有被应用,装饰器注册被忽略。
任何想法如何注册这个装饰器?我究竟做错了什么?