我正在利用AutoFac的ServiceHost.AddDependencyInjectionBehavior()
扩展(如AutoFac文档中所述)将业务层注入自托管(InstanceContextMode=每次调用)WCF服务
我的业务层使用的组件不能在每次收到新请求时重新创建(假设它需要一个持久的数据库连接)。
因此,在构建容器时,我希望将BL服务注册为单个实例,即:
builder.RegisterType<BusinessLayer>()
.SingleInstance();
WCF服务中的业务层注入工作正常;我的问题是:
Dispose()不会对容器中创建的任何服务调用:不仅是业务层本身,还有"持久"服务
我预计BL服务本身也会发生这种情况。再次从Autofac文档:
如果您有singleton组件(注册为SingleInstance()),它们将在容器的生命周期内运行。由于容器的寿命通常是应用程序的寿命,这意味着组件直到应用程序结束才会被释放
,但既然我没有明确地将其设为"SingleInstance",为什么我的"子"(Autofac注册)服务(即下面的"IPersistentService")在生存期范围为时都没有被处理?注意::如果我关闭ServiceHost 后在生存期范围内手动处理业务层服务,情况仍然如此
例如(为简洁起见,省略了IDisposable实现):
[ServiceContract]
public interface IMyService
{
void DoStuff();
}
public class MyService : IMyService
{
IBusinessLayer _bl;
public MyService(IBusinessLayer bl)
{
_bl = bl;
}
public void DoStuff()
{
_bl.BLDoStuff();
}
}
public interface IBusinessLayer
{
void BLDoStuff();
}
public class BusinessLayer : IBusinessLayer
{
IPersistentService _service;
public BusinessLayer(IPersistentService service)
{
_service = service;
}
public void BLDoStuff()
{
// Do something that requires a 'cached' / persistent component
_service.DoSomethingWithPersistentConnection();
}
}
public interface IPersistentService : IDisposable
{
void DoSomethingWithPersistentConnection();
}
Autofac注册看起来像:
builder.RegisterType<BusinessLayer>()
.SingleInstance();
builder.RegisterType<MyPersistentService>()
.As<IPersistentService>()
.OnActivated(e => e.Instance.Start());
正如Steven所提到的,您在这里遇到的是一个Captive Dependency问题。换言之,单例(BusinessLayer
,向.SingleInstance()
注册)保持生存期范围或瞬态依赖关系(MyPersistentService
,默认注册为瞬态)。
这样说,单例服务的依赖关系本身将始终是单例,无论它们是如何在容器中注册的。史蒂文链接到的马克·西曼文章中的图表很好地说明了这一点。
我认为你可以达到你的期望,但你的注册是错误的。
我的业务层使用的组件无法在每次收到新请求时重新创建(假设它需要一个持久的数据库连接)。
因此,在构建容器时,我想将BL服务注册为单实例
这就是问题所在。必须注册为singleton的是业务服务的依赖项,而不是业务服务本身。这意味着您可以让Autofac为每个WCF调用创建不同的BusinessLayer
实例,但注入的MyPersistentService
实例始终相同。这有道理吗?然后您的注册看起来像:
builder
.RegisterType<BusinessLayer>()
.As<IBusinessLayer>()
.InstancePerLifetimeScope(); // a new instance per WCF call
builder
.RegisterType<MyPersistentService>()
.As<IPersistentService>()
.OnActivated(e => e.Instance.Start())
.SingleInstance(); // one same instance for the lifetime of the application
MyPersistenService
的一个实例只有在关闭服务主机后处理完根容器(通过调用builder.Build()
创建的)后才会被处理。