[ASP.NETコア3の枠組みシークレット]依存性注入[7]:消費者サービス

IServiceCollectionコレクションは、サービス登録情報は、依存関係としてコンテナに最終IServiceProviderオブジェクトを作成するために使用されるが含まれています。あなたがサービスインスタンスを消費する必要がある場合、我々は唯一のサービスのgetServiceメソッドのタイプを指定する必要がIServiceProviderを呼び出すことができ、IServiceProviderオブジェクトは、対応するサービスレジストリに基づいて、必要なサービスインスタンスを提供します。

一、IServiceProvider

次のコード断片、IServiceProviderインタフェース定義のみのgetServiceの指定されたタイプに対応するサービスインスタンスを提供するための方法。IServiceCollectionがIServiceProviderオブジェクトを作成し、登録が挙げられるサービスを使用してオブジェクト場合、我々は、対応するサービスをご提供することができるのgetServiceメソッドと呼ばれるパラメータとして登録情報に従ってサービスへ(サービス・タイププロパティのServiceDescriptorに対応)登録されたサービス・タイプが必要サービスインスタンス。

パブリック インターフェイスIServiceProvider 
{ 
    オブジェクトのgetService(タイプのServiceType)。
}

3つのBuildServiceProvider拡張方法はIServiceCollectionでオブジェクトを作成するための過負荷は、IServiceProviderインターフェイスを反映しています。次のコードは、提供される3つのオプションを作成するオブジェクトの構成に応じて拡張型のServiceProviderオブジェクトを提供するための方法です。設定オプションのServiceProviderOptions、属性の2種類を提供していValidateScopesながら属性は、あなたが開いているため、サービスの範囲を確認する必要があるかどうかを示しValidateOnBuildの各オブジェクトはServiceDescriptorは、対応するサービスインスタンスを提供することができます登録されているよう属性は使用前検査の必要性を示しています。デフォルトでは、テストのこれらの2つのタイプが閉鎖されています。

パブリック クラスServiceProviderOptions 
{ 
    パブリック ブール ValidateScopes { 取得しますセット; }
     パブリック ブール ValidateOnBuild { 得ますセット; }
     内部 静的 読み取り専用 ServiceProviderOptionsデフォルト= 新しいServiceProviderOptions()。
} 

パブリック 静的 クラスServiceCollectionContainerBuilderExtensions 
{ 
    パブリック 静的のServiceProvider BuildServiceProvider(このIServiceCollectionサービス)
         =>BuildServiceProvider(サービス、ServiceProviderOptions.Default)。
    パブリック 静的のServiceProvider BuildServiceProvider(この IServiceCollectionサービス、BOOL validateScopes)
         => services.BuildServiceProvider(新しい ServiceProviderOptions {ValidateScopes = validateScopes})。

    公共の 静的のServiceProvider BuildServiceProvider(このIServiceCollectionサービス、ServiceProviderOptionsオプション)
         => 新しいのServiceProvider(サービス、オプション); 
}

ServiceProviderは、内部型とインタフェースのシリーズを含み、およびサービスインスタンスのこのタイプの実現のためになっているメカニズムを提供するためBuildServiceProvider拡張メソッドのIServiceCollectionを呼び出している間、常にのServiceProviderオブジェクトを返しますが、私は詳細にこのタイプを意図していない、それがあります絶えず変化、および置換処理の将来のバージョンでトレンドのこの変更は、おそらく継続されます。

getServiceメソッドIServiceProviderインターフェイスを定義することに加えて、インターフェースは、一例として機能するこれらの方法のさらなる拡張を有します。getService <T>方法サービスインスタンスは、対応するタイプの変換が返されるため、汎用パラメータの形でサービスのタイプを指定します。あなたがサービス登録のサービスタイプを指定した場合は、例外の呼び出しGetRequiredServiceまたはGetRequiredService <T>メソッドの例外InvalidOperationExceptionタイプがスローされた場合。、のgetServiceメソッドがnullを返し、存在しません。必要なサービスインスタンスが必要な場合は、我々は、通常、これら2つの拡張メソッドを呼び出します。

パブリック 静的 クラスServiceProviderServiceExtensions 
{ 
    パブリック 静的 TのgetService <T>(このIServiceProviderプロバイダ)。

    パブリック 静的 T GetRequiredService <T>(このIServiceProviderプロバイダ)。
    パブリック 静的 オブジェクト GetRequiredService(このIServiceProviderプロバイダ、タイプのServiceType); 
    
    パブリック 静的のIEnumerable <T> GetServices <T>(このIServiceProviderプロバイダ)。
    公共の 静的のIEnumerable < オブジェクト > GetServices(このIServiceProviderプロバイダ、タイプサービス種別); 
}

以前に何度か述べたように、あなたが特定のタイプに対して登録複数のサービスを追加した場合、その後のgetServiceメソッドは、常にサービスインスタンスを提供するために加え、最新のサービスを使用して登録されます。あなたはサービスインスタンスリストのセットを作成するには、登録、我々はGetServicesまたはGetServices <T>メソッドを呼び出すことができる全てのサービスを利用したい場合は、またのgetService <IEnumerableを<T >>メソッドを呼び出すことができます。

第二に、サービスインスタンスを作成します

IServiceProviderのために、対応するサービスインスタンスを取得するために、サービスの種類によって指定され、それは常に提供するサービスの種類に応じたサービスリストから対応する登録を見つけるだろう、我々はそののgetServiceメソッドを呼び出すBuildServiceProviderメソッド呼び出しIServiceCollectionコレクション、によって作成されたオブジェクトServiceDescriptorオブジェクト、および必要なサービスインスタンスを提供するために、それに応じました。

有するServiceDescriptor 三つの異なるコンストラクタ、一例として提供される最初の3つのサービスに対応して、我々は提供することができるのFunc <IServiceProvider、オブジェクト>もよく、対応するサービスインスタンスを作成するファクトリとしてオブジェクトを直接に作成するために良いサービスを提供します例我々はサービスの種類を達成することである、そのサービスは、最終的にコンストラクタを呼び出すことによって、特定の型を作成する例を提供します提供した場合は、コンストラクタは、戦略の種類によって選択されていますか?

IServiceProviderオブジェクトは道のコンストラクタを呼び出すことにより、サービスインスタンスを作成しようとしていた場合は、コンストラクタに渡されたすべてのパラメータが初期化されなければならないので、最終的に選択されたコンストラクタは、基本的な条件を持っている必要があり、それがあるコンストラクタを提供するために、IServiceProviderすべてのパラメータ約た戦略のより深い理解がコンストラクタIServiceProvider選択プロセスで使用することができる読者を与えるために、我々はこのの例により実証します。

私たちは4つのサービス・インターフェース(IFoo、IBAR、IBazとIGux)とコンソールアプリケーションでの4つのクラス(フー、バー、バズとGUX)の実現を定義しました。以下のコードセグメントに示すように、我々はパラメータがサービス・インタフェースの種類である定義三のGUXコンストラクタを定義します。IServiceProviderは、ターゲット・サービスは、我々の出力コンソールコンストラクタの実行に対応する指標でテキストのインスタンスを作成することを選択したどのコンストラクタ判断するには。

パブリック インターフェースIFoo {}
 パブリック インターフェイスIBAR {}
 パブリック インターフェイスIBaz {}
 パブリック インターフェイスIGux {} 

パブリック クラスはFoo:IFoo {}
 パブリック クラスバー:IBAR {}
 パブリック クラスバズ:IBaz {}
 パブリック クラスGUX:IGux 
{ 
    公共 GUX( IFooのFOO)=> Console.WriteLineを(" 選択されたコンストラクタ:GUX(IFoo)" )。
    公共 GUX(IFoo fooという、IBARバー)=> Console.WriteLineを(" 選択されたコンストラクタ:GUX(IFoo、IBAR)" );
    公共 GUX(IFoo fooという、IBARバー、IBazバズ)=> Console.WriteLineを(" 選択されたコンストラクタ:GUX(IFoo、IBAR、IBaz)" ); 
}

このデモプログラムを以下では、我々はServiceCollectionオブジェクトを作成しているとIFoo、IBARとIGux 3つのサービスレジストリサービス・インターフェースのために追加し、登録のためのIBazインターフェースサービスが追加されていません。私たちは、IServiceProviderは、我々はGUXオブジェクトを取得できるかどうか、IGuxインターフェースサービスのインスタンスを提供することによって作成されたでしょうか?あなたができるなら、それはそれを作成するためにどのコンストラクタを実装することですか?

クラスプログラム
{ 
    静的な 無効メイン()
    {        
        新しいServiceCollection()
            .AddTransient <IFoo、フー> ()
            .AddTransient <IBAR、バー> ()
            .AddTransient <IGux、GUX> ()
            .BuildServiceProvider()
            .GetServices <IGux> ); 
    } 
}

それは、前の2つのコンストラクタのパラメータをすべて提供できるように、IServiceProviderが提供創出によるIServiceCollectionコレクションがIFoo IBARやサービスのためのインタフェースが含まれている3つのコンストラクタでGUXでの定義は、登録されました。IServiceProviderオブジェクトによって提供することができない第三のコンストラクタIBazパラメータの型を有するからです。我々は先に説明した第一原理(IServiceProviderオブジェクトは、すべてのコンストラクタ引数を提供することができます)によると、GUXは、最初の2つのコンストラクタは、IServiceProviderは、最終的に1が行うかを選択します、正当な候補コンストラクタになるのでしょうか?

すべての有効な候補コンストラクタのリスト、例えばAの特性を有する最終的に選択されたコンストラクタ:パラメータ型コンストラクタの各候補セットについては、パラメータ・タイプのセットのコンストラクタのサブセットです。そのようなコンストラクタが存在しない場合は、例外の例外InvalidOperationExceptionタイプがスローされます。この原理によれば、GUX第2のパラメータ型コンストラクタとIFooザIBAR、IFooパラメータの一種類のみが最終的にので、GUX第二のコンストラクタを選択することになる有する最初のコンストラクタを含み私たちは、プログラムがコンソールに出力下図の例が生成されます実行します。

4-6

次に、我々は少しインスタンスのためのプログラムを変更しました。次のコードは、我々は2つのパラメータのみを持っている2つのコンストラクタGUXを、定義、パラメータの種類はIFoo&IBARとIBAR&IBazです。私たちは、IBaz /バズのサービス登録用に作成ServiceCollectionコレクションに追加されます。

クラスプログラム
{ 
    静的な 無効メイン()
    {        
        新しいServiceCollection()
            .AddTransient <IFoo、フー> ()
            .AddTransient <IBAR、バー> ()
             .AddTransient <IBaz、バズ>() 
            .AddTransient <IGux、GUX> ()
            BuildServiceProvider()
            .GetServices <IGux> (); 
    } 
} 

パブリック クラスGUX:IGux 
{ 
    公共GUX(IFooのFOO、IBARバー){}
     公共GUX(IBARバー、IBazバズ){} 
}

GUXのために2つのコンストラクタ、彼らは、パラメータIServiceProviderオブジェクトによって提供されることが可能であるが、しかし種類のパラメータコンストラクタは、すべての有効なコレクション型のコンストラクタのパラメータのセットのスーパーセットすることができない、あなたが最もIServiceProviderを選択することはできません嘉コンストラクタ。以下に示すプログラムInvalidOperationException例外を実行した後にスローされますと、コンストラクタで2つの候補から作成された最適なサービスインスタンスを選択するように求めすることはできません。(S409)

4-7

[ASP.NETコア3フレーム開示] DI [1]:制御の反転
[ASP.NETコア3フレーム開示] DI [2]:IoCのモード
[ASP.NETコア3フレーム開示] DI [3]:依存性注入モード
[ASP.NETコア3フレーム開示] DI [4]:DIフレームのミニバージョン
[ASP.NETコア3フレーム開示] DI [5]:容器を使用してサービスを提供する
[ASP.NETコア3フレームワークシークレット】依存性注入[6]:サービス登録
[ASP.NETコア3枠組みシークレット]依存性注入[7]:サービス消費
[ASP.NETコア3枠組みシークレット]依存性注入[8]:ライフサイクル・サービス・インスタンス
[ASP.NETコア3フレーム開示] DI [9]:概要リアライズ
[ASP.NETフレームワーク秘密コア3] DI [10]:サードパーティの依存性注入アダプタフレーム

おすすめ

転載: www.cnblogs.com/artech/p/inside-asp-net-core-03-07.html