作用域代理装饰器中的简单注入器装饰器工厂

Simple Injector decoratee factory in scoped proxy decorators

关于 docs of SimpleInjector 在 decoratee 工厂中使用装饰器模式,我 运行 遇到了以下问题。

假设我有一个类似 ThreadScopedCommandHandlerProxy<T> 的实现如下:

public class LifetimeScopeCommandHandlerProxy<T> : ICommandHandler<T>
{
    private readonly IScopeStarter _scopeStarter;
    private readonly IServiceFactory<ICommandHandler<T>> _decorateeFactory;

    public LifetimeScopeCommandHandlerProxy(
        IScopeStarter scopeStarter,
        IServiceFactory<ICommandHandler<T>> decorateeFactory)
    {
        _scopeStarter = scopeStarter;
        _decorateeFactory = decorateeFactory;
    }

    [DebuggerStepThrough]
    public void Handle(T command)
    {
        using (_scopeStarter.BeginScope())
        {
            ICommandHandler<T> handler = _decorateeFactory.CreateInstance();
            handler.Handle(command);
        }
    }
}

通常我会在代理中注入一个 Func<ICommandHandler<T>>,但我想从中抽象出来并创建一个 IServiceFactory,它在内部只是这样做:

public class SimpleInjectorServiceFactory<TService> : IServiceFactory<TService>
{
    private readonly Func<TService> _factory;

    public SimpleInjectorServiceFactory(Func<TService> factory)
    {
        _factory = factory;
    }

    public TService CreateInstance()
    {
        return _factory.Invoke();
    }
}

你可以通过查看 class 名称来了解这背后的原因,这是一个 Simple Injector 特定工厂。现在我知道使用这样的工厂抽象会引入代码味道。但在这种情况下,它只能用作基础结构组件。我的想法是,我希望代理可以被多个 libraries/applications 使用,因此使其成为应用程序架构中的通用组件。

现在的问题当然是我遇到以下异常:

For the container to be able to use LifetimeScopeCommandHandlerProxy<TCommand>
as a decorator, its constructor must include a single parameter
of type ICommandHandler<TCommand> (or Func<ICommandHandler<TCommand>>)
- i.e. the type of the instance that is being decorated.
The parameter type ICommandHandler<TCommand> does not currently exist
in the constructor of class LifetimeScopeCommandHandlerProxy<TCommand>.'

现在这个异常消息 crystal 清楚了,我明白了这背后的原因。但是,我还是想知道是否可以绕过异常?

I'd like to know if it's possible to bypass the exception

如果不完全绕过并重新实现 Simple Injector 的装饰器子系统,就无法做到这一点。

Simple Injector 的子系统通过包装装饰器来拦截服务的构建。尽管装饰器子系统会将装饰器及其依赖项的创建外包给 Simple Injector 的核心基础设施,但它会覆盖捕获装饰实例的依赖项的创建。这种行为在装饰器子系统中是硬编码的,这意味着不可能将类型的装饰者移动到装饰器的子系统 class。