【翻訳】WebAPIの、Autofac、およびライフサイクルスコープ

説明

オリジナル住所:http://decompile.it/blog/2014/03/13/webapi-autofac-lifetime-scopes/

入門

これはAutoFacについての記事であるライフサイクルスコープ記事の。

約ライフサイクルドメインは常に、困難な命題となっている概念のいくつかは、容易など、誤解や混乱を引き起こす可能性がシングルトンドメイン(PerLifetimeScope)と内部要求シングルトン差があり、それらは互換的に使用できるもの(InstancePerRequest)ように......

私はstackoverflowの上、この記事へのリンクを見つけるまで、これらの問題以前に、私を悩ませてきた、著者は徹底的に私はそれが翻訳追いやら以上のことを感謝したいと思い、すべて私の疑問に答え、サンプルコードを使用+方法を示しますダウン。

テキストを読む前に、あなたは、次の質問を見てみることができますあなたがお祝いの言葉、その後、これらの問題に非常に明確にされている場合は、あなたがこの記事を読んで時間を無駄にする必要はないように十分に強いてきた、あなたは右折に直接行くことができます:

  1. ドメインシングルトン(PerLifetimeScope)それは何を意味するのでしょうか?

  2. シングルトン内の要求(InstancePerRequestは)それは何を意味するのでしょうか?

  3. 単一ケース内要求シングルトン内違いは何ですか?プロジェクトのWebAPIの種類では、彼らは互換的に使用することはできますか?

  4. .NETコア中のAutoFac 要求シングルトン(InstancePerRequest)はもはや有効ではないが、オブジェクトが持っているように、いくつかの必要性を登録する要求内の単一の実施形態(例えばDbContext EFのように)、それは使用することができ、単一の実施形態技術を置き換えることを(PerLifetimeScope)それは?インパクトとは何ですか?

これらの問題のいずれかが、まだ疑問を持っている場合は、私がこの記事は(それは私のためだったのと同じ)であなたのために参考になると信じています。

プロンプト

  1. 上述物品HTTPリクエストシングルトンに(InstancePerHttpRequest)およびAPIリクエストシングルトン内連結により置換(InstancePerApiRequest)今AutoFac時代遅れ、要求の単一症例(InstancePerRequest)

  2. ソースコードの原作者は、GitHubのオープンソースの記事の最後のアドレスです。私はまた、ダウンロードまたは参照するには行くことができる必要がある、フォーク、最新バージョンへのアップデートAutoFacだ、と中国の文書を追加しました私のGitHubは

  3. この記事は、友人や初心者が、私は私が見ることができる前に、あなたはAutoFac技術文書を読むために行く、または下に書かれたことができます示唆場合はすでに、前提条件として、依存性注入とAutoFacの基本を知っているデフォルトの読者に基づいています2 .NETの依存性注入横たわっ時間半の記事を〜

オリジナル

多くの場合、非常に悩んで、私たちの提案がある場合、我々はAutoFac(あるいは依存性注入のための他の容器)を使用する場合は、そのライフサイクルの範囲です。

:あなたが初心者であれば、私はニコラスBlumhardtの素晴らしい記事読むことをお勧めしAutofac生涯プライマーをあなたが繰り返しこの知識を消化するために数回を読むために必要があるかもしれないことを考えると、私はあなたがブックマークを保存することができますことを示唆しています。

AuotoFacのために、私は多くの場面で、このような質問を聞いたことがあります:

ドメインシングルトン(InstancePerLifetimeScope)、HTTPリクエストシングルトン(InstancePerHttpRequest)と、単一のケース(InstancePerApiRequest)内のAPIリクエスト内の違いは何ですか?

私はいつもこの質問によって当惑されており、これまでのところ、私は満足のいく答えを見つけることができます。だから、今日私はこの質問に答える自分自身をしようとします。

まず、私の究極の結論を投げます:

  • あなたが登録したい場合に依存しているすべてのドメインが解決されている可能性があり、使用してくださいシングルトンドメイン(InstancePerLifetimeScopeを)。ドメインの解除に連動して、依存関係のあなたのライフサイクル。このドメインの場合はルートドメインが、それはプログラムの最後まで存在します。

  • あなたが唯一の要求コンテキストの要求タイプ(HTTP / API)で解決される頼る登録をしたい場合は、使用要求にシングルトンを(InstancePerApiRequest / InstancePerHttpRequest)。リクエストの終了後に依存リリース。

ここで私はニコラスは、この作品の良い部分を行っている、ライフサイクルの概念と範囲を説明するために行くことはありません、私はまた出て掲載彼の記事は、上記のリンクを入れています。だから、私はあなたがすでに依存性注入の基本的な知識を持っていると仮定しますと、今、あなたはちょうど彼らがどのように動作するかWebプログラムのために知ってほしいです。

よりよく説明するために、私は彼らのレースを実行しようとしてダウンに必要なダウンロードすることができます簡単なプログラムを書きました。私は4つのでプログラムを作成したResolvablesカテゴリ-それらのそれぞれは非常に簡単で、唯一の機能は、サービスが出て解析されたところからで実証することです。そのコードを登録し、以下のとおりです。

private static void RegisterResolvables(ContainerBuilder builder)
{
    builder.RegisterType<SingletonResolvable>()
        .SingleInstance();
 
    builder.RegisterType<PerLifetimeResolvable>()
        .InstancePerLifetimeScope();
 
    builder.RegisterType<PerRequestResolvable>()
        .InstancePerApiRequest();
 
    builder.RegisterType<PerDependencyResolvable>()
        .InstancePerDependency();
}

クラスを解析するための責任のプログラムもあり、その唯一のタスクは、上記の4つの解析のために責任があるResolvablesカテゴリを。以下は、クラスのコンストラクタであります:

public ResolvableConsumer(
    SingletonResolvable singleton,
    PerLifetimeResolvable lifetime,
    PerRequestResolvable request,
    PerDependencyResolvable dependency)
{
    // ...
}

今、私は素晴らしい事をしなければなりません!私が作成しScopeTokenたクラスを、そしてそれがどのような範囲外に解析するために自分自身を示し、その後、4つの聞かせできるように、単に何それをカプセル化するResolvablesクラスはこれに依存しているScopeTokenクラス。ログインScopeTokenクラス、我々はプログラムが生成されますどのような変更最後に、そのライフサイクルを観察するためのスコープを変更することができます。ここで、我々はそれを最初に登録し一時的なインスタンス(InstancePerDependencyは)それを試してみます。

private static void RegisterToken(ContainerBuilder builder)
{
    var tokenRegistration = builder.RegisterType<ScopeToken>();
 
    // TODO: 挨个尝试
    // tokenRegistration.SingleInstance();
    // tokenRegistration.InstancePerLifetimeScope();
    // tokenRegistration.InstancePerApiRequest();
    tokenRegistration.InstancePerDependency();
}

私たちは要求できTestControllerGETリクエストで私たちの手順をテストします。私は(このツールを使用することに、あなたはを参照することができHTTPieのWeb要求をシミュレートするためのツールを使用スコットHanselman氏のインストールノート

今私達の準備が完了している、我々は登録された異なるライフサイクルスコープを使用して一緒に見て、次は、解決しますScopeTokenインパクトの種類を。

例過渡シングル(InstancePerDependency)

私たちは、自分のドメインのライフサイクルを指定しない場合、AutoFac登録コンポーネントを使用する場合は、ドメインがデフォルトのオプションとなります。技術文書で説明したようにされています。

登録アセンブリでマークフィールドは、各コンポーネントまたは各パスは(解決の依存)は、新しいインスタンスに解析されます。

私たちは、インターフェイスが起こるGET何を呼び出すために、見てください:

PerDependency

予想通り、それぞれ解析对象の中には、独自のトークンのみを注入しています。見て、依存性の注入は、働いていました!

我々はいくつかの興味深い場所を見ることができます:

  • SingletonResolvableトークン根域内(ルートスコープ)解析されました

  • AutofacWebRequestのと呼ばれるドメインからのすべてのクラスのトークンが解析され、他の決意

下図のように:

PerDependency1

好奇心から、私たちはもう一度、何が起こるかと呼ばれるインターフェースを見れば:

PerDependency_2

トークン#1は変更されていません。プログラムのライフサイクルとルートドメインが一致しているためです。つまり、SingletonResolvableオブジェクト、およびそれが依存するScopeTokenプログラムは、これまでに実行を停止するまで、オブジェクトが存在します。

代わりに、理由は、#2、#3、#4が全て解放されたトークンAutofacWebRequest域のライフサイクルのWeb要求と一貫性のあるの。要求が終了オフ直後にリリースされたときに要求が開始されたときには、フィールドが作成されています。

グローバル・シングルトン(SingleInstance)

private static void RegisterToken(ContainerBuilder builder)
{
    var tokenRegistration = builder.RegisterType<ScopeToken>();
    tokenRegistration.SingleInstance();
}

簡単には、それがグローバルシングルトン、その名前で表されるように、その意味で理解して次へ:任意の時間には、一意のインスタンスになります。実際、Autofacシングルトンオブジェクトは、に起因する根域他のすべてのフィールドは、ルートドメイン内のサブドメインであるが、(ルート・スコープ)(または「コンテナ」範囲と呼ばれます)。ここでは、出力コール・インタフェースは次のとおりです。

SingleInstance

再び予想されるように、解決される各オブジェクトは同じであるScopeTokenインスタンス。

SingleInstance1

二つの点に注意する必要があります。

  1. すべての例は、単一のルートドメインにある、と私はすでに限り、プログラムのライフサイクルとルートドメインとして、述べています。
  2. コンポーネントを解析するとき、依存親クラスのドメインを見つけるために追跡されますAutoFac

例単一ドメイン(PerLifetimeScope)

private static void RegisterToken(ContainerBuilder builder)
{
    var tokenRegistration = builder.RegisterType<ScopeToken>();
    tokenRegistration.InstancePerLifetimeScope();
}

ここから、物事は面白くするために開始します。ドキュメントドメインの単一例AutoFacの解釈次のように:

ライフサイクル・スコープ、依存性または解決()オブジェクトによって解析後続の各コンポーネントに登録され、同じスコープのライフサイクルは同一であり、それらは同じ単一の実施形態を共有するが、異なるライフサイクル影響以内それは異なっています。

、上記の瞬間的なDOの単一のケースを例を覚えていますか?SingletonResolvableクラスは他のルートドメインで解析されResolvablesたクラスが解決されますAutofacWebRequest域のは、何が起こるか内の単一のケースを見てみましょう:

PerLifetimeScope

正如预期的,我们有两个“激活”的域,而且每个域内都有一个ScopeToken实例。

PerLifetimeScope1

让我们来看下当再次调用接口会发生什么:

PerLifetimeScope_2

和之前的瞬时单例一样,处在根域内的Token #1一直存在着,而处在AutofacWebRequest域内的Token #2在请求结束后被释放掉了。

一直以来有一个普遍的错误认知,就是认为在WebAPI项目中如果组件被注册为域内单例(InstancePerLifetimeScope)的话,那么意思就是它将存活在一次request请求内,即它的生命周期就是一次request请求的生命周期。但是正如上面的例子所展示的,这种认知是错误的。

被注册为域内单例的组件,它的生命周期是由解析它的域所决定的。

因为SingletonResolvable实例是在根域内解析它的token,所以这个token实例就存在于根域内,而不是一次web请求的生命周期域。之前已经说过,这里我要再重复一遍:这个token会一直存在直到整个应用程序停止运行为止(即IIS工作进程被回收时)。任何对象只要是在根域内要求获取依赖的ScopeToken,那么它就会得到这个唯一单例的对象。

Api请求内单例(InstancePerApiRequest)

private static void RegisterToken(ContainerBuilder builder)
{
    var tokenRegistration = builder.RegisterType<ScopeToken>();
    tokenRegistration.InstancePerApiRequest();
}

最后,也是最重要的,让我们来看下Api请求内单例。下面是调用接口后的情况:

PerApiRequest

请求出现了一个令人不快的异常,内容是:

被请求获取的实例所在的域内,找不到一个标签为‘AutofacWebRequest’的域。这通常表明,有一个被注册为每次HTTP请求内单例的组件被一个全局单例的组件请求获取(或者是类似的其他场景)。web项目通常是从DependencyResolver.Current或者ILifetimeScopeProvider.RequestLifetime中获取依赖,但是不允许直接从根容器中获取。

为了明白为什么会发生这样的异常,我们需要回到AutoFac的技术文档上来。里面说,Api请求内单例(InstancePerApiRequest)实际上是每个匹配域内单例(InstancePerMatchingLifetimeScope)的一种特殊情况,文档原文是这样的 :

用Api请求内单例来注册组件,那么每个依赖组件或者每次通过Resolve()解析,只要是在打了统一标签名称的域内,就会得到同一个对象,即它们共享同一个单例。在这个特定标签域下面的所有子域中,依赖组件也会共享其父域中的单例。如果在当前域和它的父域中都找不到这个标签域,那么一个类型为DependencyResolutionException的异常将会被抛出。

具体来说,Api请求内单例(InstancePerApiRequest)实质上是在一个特定标签域内单例,正如你所猜测的,这个特定标签域就是AutofacWebRequest域。这个域会在一次请求开始时被创建,并且在请求结束后被立即释放。综上,如果使用Api请求内单例(InstancePerApiRequest)来注册组件,那么这个组件只允许在AutofacWebRequest域内或其子域内被解析。

私たちの異常が解析で発生しSingletonResolvableたオブジェクト。我々のようにそれを登録する前に、グローバルなシングルトン(SingleInstance)、それがである根域内部、そして根域(名前が示すように)他のすべてのドメインの親ドメインです。分析的依存性は、唯一の上方に依存親ドメインを輝く見つけるために、サブフィールドの方向に向けて見下すことは許されません。要約すると、SingletonResolvable我々は行かない必要がありAutofacWebRequest标签域、それはその依存関係を取得することはできませんので、その依存性を見つけるために、内ScopeToken、そして再び、私たちは、例外の上に投げられます。

PerApiRequest1

HTTPは、単一の実施形態(InstancePerHttpRequest)を要求します

私は上記の持っていない単一の実施例HTTPリクエスト、その自然との、(InstancePerHttpRequest)を、単一の要求APIの実施形態(InstancePerApiRequest)と同じですが、唯一のHTTPリクエスト(WEBAPIの相対的な用語を)ため。実際には、それはまだ内部的に使用され、単一のケース内にマッチした(InstancePerMatchingLifetimeScope)、同じ、とも呼ばれるタグを一致させるために使用される名前AutofacWebRequestしたがって、それが登録されているHTTPリクエストの単一の実施形態のコンポーネントを解決として登録することができる単一のAPIリクエスト内の実施例オブジェクト、およびその逆。

うまくいけば、この記事では、より良いWebAPIのプロジェクトのスコープの下AutoFacのライフサイクルを理解するのに役立ちます。自由にすることができます必要としている友人のソースコードをダウンロードして使用します。


Gerrodは2014年5月13日、.NET版に掲載されました

終了

先頭を見に戻っていくつかの問題を読んだ後、それはすでに答えを持っていないのですか?

おすすめ

転載: www.cnblogs.com/RayWang/p/11232911.html