关于在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>.'
现在这个异常消息非常明确,我理解这背后的原因。但是,我仍然想知道是否有可能绕过这个例外?
答案 0 :(得分:1)
我想知道是否可以绕过异常
没有完全绕过并重新实现Simple Injector的装饰子系统,就没有办法做到这一点。
Simple Injector的子系统通过包装装饰器来拦截服务的构建。虽然装饰器子系统会将装饰器及其依赖关系的创建外包给Simple Injector的核心基础结构,但它将覆盖捕获装饰实例的依赖关系的创建。这种行为在装饰器子系统中是硬编码的,这意味着不可能将类型的decoratee移动到装饰器的子类。