2017-06-11 11 views
2

私は、インスタンスをコンテナから解決するたびに新しい生存範囲を取得する方法を理解しようとしています。私は、Autofacについて知る必要のある依存コンポーネントなしでこれをしたいと思います。Autofac名前空間を使用しないで解決する暗黙のスコープ

"マスターサーバー"(IMasterServer)コンポーネントとゼロ以上の "セッションサーバー"(ISessionServer)コンポーネントを持つ.NETコアサーバーアプリケーション(コンソールアプリケーション)を作成しています。マスターサーバーとセッションサーバーの両方には独自のIMessageBrokerの依存関係があります。マスターサーバーは、メッセージブローカーからメッセージを取得するたびに、新しいセッションサーバーを作成します。

キャッチは、各セッションのサーバインスタンスは、独自のIMessageBroker必要、と私はメッセージ・ブローカーは、単一のインスタンスである必要がISessionServerの他のサブコンポーネントもIMessageBrokerにアクセスする必要がありますので、私はInstancePerDependency()を使用することができるとは思わないということですセッションの範囲内でだから私の考えは、マスターサーバーが新しいセッションを生成するときに、新しいライフタイムスコープ内でそれを実行する必要があり、InstancePerLifetimeScope()を使用してIMessageBrokerの依存関係を登録できるということです。

ISessionServerファクトリをIMasterServerに挿入すると、ファクトリが呼び出されるたびに、結果のISessionServerインスタンスに対して新しい有効期間スコープが作成されるようになりますか?また、どのコンポーネントもAutofacについて知る必要がないように、これをどのように行うことができますか?

これら2つのSOの質問の両方Owned<T>関係使用することをお勧め:私は何かが欠けていない限り、コンポーネントがその中に依存関係が注入されることを意味している。しかし、

Can I create an implicit Lifetime scope within a factory?

Is it possible to create a new scope whenever a component is resolved?

を(私の場合はIMasterServer)Autofacについて知る必要があります。なぜなら、そのctor署名にはOwned<T>タイプが含まれていなければならないからです。

私がこれまで持っているもの:

using Autofac.Features.OwnedInstances; 

class MasterServer : IMasterServer 
{ 
    private IMessageBroker mMessageBroker; 
    private Func<Owned<ISessionServer>> mSessionServerFactory; 

    public Master(
     Func<string, IServerMessageBroker> messageBrokerFactory, 
     Func<Owned<ISessionServer>> sessionServerFactory 
    ) 
    { 
     mMessageBroker = messageBrokerFactory("master"); 
     mSessionServerFactory = sessionServerFactory; 
    } 
} 


class SessionServer : ISessionServer 
{ 
    private IMessageBroker mMessageBroker; 
    private string mId; 

    public SessionServer(
     Func<string, IMessageBroker> messageBrokerFactory 
    ) 
    { 
     mId = Guid.NewGuid().ToString(); 
     mMessageBroker = messageBrokerFactory(mId); 
    } 
} 

あなたがマスターサーバー具象クラスがOwned<T>関係タイプを使用してセッションファクトリを定義するためにAutofac.Features.OwnedInstances名前空間を使用する必要があることがわかります。

ISessionServerが、MasterServerに注入された工場で解決されるたびに、使用中の特定のDIコンテナについて何かを知る必要がなく、新しい寿命スコープを作成するにはどうすればよいですか?

答えて

0

私は、Autofac特有のコードを工場のクラスに流し込むことは、2つの悪いことではないことを常に感じていました。 私はあなたの中にいたならば、Owned<T>クラスを使用して、それを1日と呼びます。これは優れたソリューションであり、いつものようにオートファックですべてのコンポーネントを自動的に処分します。

Disposeまたはご自分のSessionServerに電話することを忘れないでください。必要な場合は、リソースがリークします。

AFAICT Autofacアプローチでは、100%DIフリーコードを書くことはできません。ですから、どこかで参照する必要があります。

Owned<T>を含む単一の参照はかなり受け入れられるようです。

あなたのデザイン(またはあなたが含む部分)に問題があることを指摘してください.ISessionServerを使い捨てスコープに簡単にリンクする方法はありません。

例:ファクトリクラスを公開してから、SessionServerが単独で出力されます。 このようにスコープを管理するのは難しくなります。

クリーナーアプローチは、usingステートメントに使い捨てを使用することです:入力用

using (var sessionServer = sessionFactory.GetServer()) 
{ 
    // do something with sessionServer. 
} 
+0

感謝。私はこのアプリケーションを開発し続けているので、貴重なAutofac機能を実装することで、Autofacについて知る必要があるコンポーネントが増えていく場所があることがわかりました。私はそれを受け入れるべきだと思います。 –

+0

'SessionServer'をusingブロックで囲むという提案については、' MasterServer'が 'SessionServer'インスタンスの集合にハングする必要があるので、私はそれを行うことはできません。それは処分されたときに処分されます。 –

+0

私は、あなたが特定の場所でオートファックの使用を維持することをお勧めします。たとえば、 'SessionServerHandle'クラスを' getSessionServer() 'メソッドを実装させ、特定のAutofacスコープの作成、' SessionServer'インスタンスのインスタンス化と破棄を行うことができます。つまり、作業単位を管理するクラスです。 –

関連する問題