2017-02-02 6 views
0

は、私は(Autofac documentationで説明したように)AutoFacのServiceHost.AddDependencyInjectionBehavior()拡張子を活用することで自己ホスト型(InstanceContextMode =パー・コール)WCFサービスへのビジネス層を注入していはAutofacは自己ホスト型WCFサービスとオブジェクトの処分で

私のビジネスレイヤーは、新しいリクエストが来るたびに再作成できないコンポーネントを使用します(永続的なデータベース接続が必要な場合)。このように

、すなわち、私はシングルインスタンスとしてBLサービスを登録したいコンテナを構築:

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

をWCFサービスへのビジネス層の注入が正常に動作しています。

Dispose()は、コンテナに作成されたすべてのサービスで呼び出されません。ビジネス層自体だけでなく、永続的なサービスも呼び出されます。

私はこれがBLサービス自体のために起こると思います。再びAutofac docsから:あなたはシングルトンのコンポーネントがある場合は

(SingleInstanceとして登録を())彼らはコンテナの生活のために生きます。コンテナの寿命は通常アプリケーションの寿命であるため、アプリケーションの最後までコンポーネント は処分されません。

が、生涯のスコープがあるときに、なぜ私の「子」(Autofac-登録)サービス(以下すなわち「IPersistentService」)のどれもが配置されていない - 私は明示的に「SingleInstance作っていないよという与えられました'? 注::私は例えばのServiceHost

を閉じた後、私は手動で生涯の範囲内でビジネスレイヤのサービスを処分した場合、これはまだケースです(簡潔にするため省略IDisposableを実装):のようなものを探してAutofac登録して

[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(); 
} 

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

builder.RegisterType<MyPersistentService>() 
    .As<IPersistentService>() 
    .OnActivated(e => e.Instance.Start()); 
+0

"ライフタイムスコープが「私の」子(Autofac登録)サービス(すなわち、以下の「IPersistentService」)のいずれも廃棄されないのはなぜですか?この問題は、一般的に[キャプティブ依存関係](http://blog.ploeh.dk/2014/06/02/captive-dependency/)と呼ばれます。 – Steven

+0

Yip、それはそれを説明します - その説明へのリンクに感謝します。 – Ive

答えて

1

スティーブンが述べたように、あなたがここで経験することはキャプティブ依存関係の問題です。つまり、シングルトン(BusinessLayer、で登録)は、ライフタイムスコープまたは一時的な依存関係を維持します(MyPersistentService、デフォルトでは一時的に登録されています)。

シングルトンサービスの依存関係は、コンテナにどのように登録されていても、常にシングルトン自体になります。スティーブンがリンクしている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の1つのインスタンスは、あなたがサービスホストを閉じた後(あなたがbuilder.Build()を呼び出すことによって作成した)のみルートコンテナを配置した後に処分されるだろう。

+0

説明をありがとう - はい、@スティーブンも述べたように、いわゆる「キャプティブ依存」はまさに私の問題です。しかし、私は本当にAutofacのオブジェクトの処分を利用して「永続的な」サービスを整理したいと思っています。私はそれらをシングルトンとして定義すると、これは可能になると思われます。したがって、BLサービスをシングルトンにすることでこれを回避しようとしています。 – Ive

+0

私はそれを取得しません。要求ごとに永続的なサービスを再作成できない場合は、各要求のたびにそれを破棄する必要があります。これは私には矛盾しているようです。 –

+0

私は、リクエストごとにそれらを廃棄するのではなく、むしろサービスを停止したいと思っています。サービスの有効期間は、WCF serviceHostが開いている期間です。 – Ive

関連する問題