我有一个X
在 Autofac 中注册为单实例的类,因为创建它的成本相当高。
X
有一个DoSomething
执行某些操作的方法。但是,要在 中完成任务DoSomething
,X
需要额外的依赖项。通常,我会将它们注入构造函数中,但在这种情况下,这会变得很困难,因为依赖项绑定到更窄的范围,例如 instance-per-httprequest 或 instance-per-lifetime-scope。我不能使用Func<T>
,因为这仍然会解析委托被实例化的生命周期中的对象,所以我什么也得不到。
下一个选项是将依赖项作为参数传递给DoSomething
,但是存在依赖项的事实实际上只是一个实现细节。事实上,我通过一个接口访问 X。我宁愿不通过添加此参数来导致抽象泄漏。
当然,在方法中手动解决依赖关系(即服务定位器样式)也不是很好。即便如此,我也有一个问题是我不确定如何访问正确的IComponentContext
. 该类可以用在 Web 应用程序或常规应用程序中,或在 Web 应用程序的线程中,但在任何请求之外。我如何确定“当前”生命周期范围?
所以基本问题是这样的:
class X : ISomething
{
public void DoSomething()
{
IDependency dependency = ?;
dependency.UseMe();
/* more stuff */
}
}
理想情况下,我希望能够向构造函数中注入一些东西,以便稍后允许我解析当前生命周期范围内的实际对象,如下所示:
class X : ISomething
{
IResolveLater<IDependency> dependencyResolver;
public X(IResolveLater<IDependency> dependencyResolver){
this.dependencyResolver = dependencyResolver;
}
public void DoSomething()
{
IDependency dependency = dependency.Resolve();
dependency.UseMe();
/* more stuff */
}
}
我当然在这里闻到了设计问题,但我真的不能指望它。我该如何解决这个一般性问题:一个长期存在的对象,它需要本地范围内的短期对象来进行单个操作。我通常更喜欢不同的顺序:短期对象取决于长期对象。
我也在考虑以某种方式将长期存在的东西从 X 中移出,并创建一个额外的、短期的类XHelper
来充当某种“适配器”:
class X
{
void DoSomething(IDependency dependency)
{
/* do something */
}
}
class XHelper : ISomething
{
X x;
public XHelper(X x, IDependency dependency)
{
this.x = x;
this.dependency = dependency;
}
public void DoSomething()
{
x.DoSomething(dependency);
}
}
因此,当我需要 ISomething 时,我将根据需要解析 XHelper(而不是 X),它会自动注入适当的依赖项。我需要为此引入一个额外的类型,这有点麻烦。
我怎样才能以最优雅的方式解决这种情况?