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

时间:2017-02-02 09:22:29

标签: wcf autofac

我通过利用AutoFac的ServiceHost.AddDependencyInjectionBehavior()扩展程序将业务层注入自托管(InstanceContextMode = per-call)WCF服务(如Autofac documentation中所述)

我的业务层使用每次新请求进入时都无法重新创建的组件(假设它需要持久的数据库连接)。

因此,在构建容器时,我希望将BL服务注册为单个实例,即:

builder.RegisterType<BusinessLayer>()
    .SingleInstance();

WCF服务中的业务层注入工作正常;我的问题是:

Dispose()不会在容器中创建的任何服务上调用:不仅仅是业务层本身,而是“持久性”服务。服务也是如此。

我希望BL服务本身能够实现这一点。再次来自Autofac docs

  

如果你有单件组件(注册为SingleInstance())它们将在容器的生命周期中存活。由于容器寿命通常是应用程序的生命周期,因此它意味着组件   在申请结束前不会被处理。

,但为什么没有我的孩子&#39; (Autofac注册的)服务(即下面的&#39; IPersistentService&#39;)在终身范围被处理时 - 假设我没有明确地制作它们&#39; SingleInstance&#39 ;? 注意::如果我在关闭ServiceHost后手动处理生命周期范围内的业务层服务,情况仍然如此

E.g。 (为简洁起见,省略了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());

1 个答案:

答案 0 :(得分:1)

正如史蒂文所说,你在这里遇到的是一个俘虏依赖问题。换句话说,单{(BusinessLayer,注册.SingleInstance())保持生命范围或瞬态依赖(MyPersistentService,默认情况下注册为瞬态)。

这样,单身服务的依赖关系本身就是单身人士,无论他们如何在容器中注册。 Steven链接到的Mark Seeman's article中的图表可以很好地了解这一点。

我认为你可以实现你的期望,但你的注册是错误的。

  

我的业务层使用每次新请求进入时都无法重新创建的组件(假设它需要持久的数据库连接)。

     

因此,在构建容器时,我想将BL服务注册为单个实例

这就是问题所在。它是必须注册为单身的业务服务的依赖,而不是业务服务本身。这意味着您可以让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()的一个实例。