具有自托管WCF服务和对象处理的Autofac



我正在利用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()创建的)后才会被处理。

最新更新