作用域代理装饰器中的简单注入器装饰器工厂
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。
关于 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。