web-dev-qa-db-ja.com

Autofac-InstancePerHttpRequestとInstancePerLifetimeScope

2つのスコープの違いは何ですか?

各レイヤー(リポジトリ、サービス、MVCアプリ)でModule(s)を構築していますが、InstancePerHttpRequestを使用するにはAutofac.Mvcアセンブリが必要です。

リポジトリおよびサービスレイヤーで使用するスコープはどれですか?

56
Sam

InstancePerHttpRequestInstancePerApiRequestは本質的に同じことを行います-個別のWebリクエストごとにサービスの単一のインスタンスを取得します。残りの回答にはInstancePerHttpRequestを使用しますが、これら2つは互換性があることに留意してください。

InstancePerLifetimeScopeは、サービスを要求するライフタイムスコープごとにサービスの新しいインスタンスが作成されることを意味します。各Webリクエストは、独自の新しい有効期間スコープを取得するため、実際には、多くの場合、これら2つはまったく同じことを行います。

唯一の本当の違いは、InstancePerHttpRequestの下に登録されたサービスがあり、SingleInstanceとして登録されている別のサービスからそれらのサービスの1つを要求する場合に発生します。このシナリオでは:

  • SingleInstanceコンポーネントはrootスコープに存在します
  • InstancePerHttpRequestコンポーネントは、ルートスコープのchildである「AutofacWebRequest」と呼ばれるスコープに存在します

Autofacは、子スコープからの解決を許可しません。したがって、本質的に、SingleInstanceサービスはInstancePerHttpRequestサービスを見つけることができません。

ただし、このシナリオでInstancePerLifetimeScopeの代わりにInstancePerHttpRequestを使用した場合、サービスは問題なく解決します。

このすべてを詳細に説明しようとするダウンロード可能なコードでかなり網羅的な記事を書きました- こちらを参照 。記事からの引用:

ここでよくある誤解の1つは、WebAPIアプリケーションでInstancePerLifetimeScopeにコンポーネントを登録すると、コンポーネントがWebリクエストのスコープ内に存在することを意味します。つまり、「Lifetime」は「WebリクエストのLifetime」を指します。ご覧のとおり、これは誤りです。

コンポーネントの寿命は、それが解決されたスコープによって決まります。

SingletonResolvableはルートスコープからトークンを解決するため、そのトークンインスタンスはWebリクエストのスコープではなく、ルートスコープに存在します。以前にも言ったことがありますが、もう一度言います。このトークンは、アプリケーション全体が破棄されるまで生き続けます(例IISワーカープロセスがリサイクルされます)。ルートスコープのScopeTokenには、そのトークンへの参照が与えられます。

これが役に立てば幸いです。この質問は今ではかなり古いものですが、それでも非常に重要です。

111
gerrod

オブジェクトの存続期間について完全に決定できるアプリケーション内の唯一の場所は、コンポジションのルートです。

この場合、競合があります-MVC統合によって提供される拡張メソッドにアクセスすべきではない汎用モジュールがありますが、ライフタイムが適切に管理されるためには、それにアクセスする必要があります。この場合、モジュールがInstancePerLifetimeScopeのような妥当なデフォルトを提供できる場合、それがモジュールレベルで行うことです。次に、コンポジションルートがその動作をオーバーライドできるようにします。この場合、構成ルートはライフタイムをInstancePerHttpRequestに変更します。最後の登録が以前の登録を上書きするため、正常な状態にある必要があります。

実際には、いくつかの理由により、特定のレイヤーを含むアセンブリと共存するモジュールを作成することから遠ざかりました。

  1. Autofacへの依存関係を導入しますが、コンポジションルート以外では必要ありません。
  2. モジュールは、そのライフタイムがどのように管理されるべきかを知っていることを示唆しますが、通常はそうではありません。もしそうなら、なぜそのライフタイム管理を提供するファクトリーまたは他のクラスを提供しないのですか?

代わりに(および保証するのに十分な大きさのプロジェクトで)、構成ルートレベルでモジュールを作成します。このレベルでは、モジュールの相互接続方法について明確な知識があるためです。モジュールを含み、デフォルトのコンポジションルートとして機能するIocアセンブリを作成することもありますが、これは「実際の」コンポジションルート(たとえば、プルするコンソールまたはMVCアプリケーション)でオーバーライドされることがよくあります。 Iocアセンブリ)。

8
Kaleb Pederson

Autofacでは、有効期間ごとスコープは、ネストされた有効期間を使用してカスタムスコープを作成する一般的な方法です。

InstancePerLifetimeScopeを使用すると、リクエストごとスコープが得られます。これにより、単一のリクエストのコンポーネントライフタイムが追加され、このコンポーネントに対してInstancePerLifetimeScropeが内部的に使用されます。

これが必要なすべての場所でInstancePerLifetimeScopeを使用するか、サービスレイヤーでAutofac.Integration.Mvc Assemblyへの参照を持つことが問題である場合-リクエストの開始ごとにネストされたスコープを手動で作成し、InstancePerLifetimeScopeを使用します。

2
whyleee