作用域代理装饰器

时间:2017-07-11 11:03:05

标签: c# simple-injector

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

假设我有一个类似的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();
    }
}

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

现在问题是,我得到以下异常:

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>.'

现在这个异常消息非常明确,我理解这背后的原因。但是,我仍然想知道是否有可能绕过这个例外?

1 个答案:

答案 0 :(得分:1)

  

我想知道是否可以绕过异常

没有完全绕过并重新实现Simple Injector的装饰子系统,就没有办法做到这一点。

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