サービスは、長い時間のために、バックグラウンドで実行する必要があるベアラ.NETのコアは、ベアリング(ホスティング)システムを持っている、ASP.NETコアサービスは、それを運ぶのシステムの1つのアプリケーションだけです。キャリア注入システムは常に、サービス時に必要なベアラサービスでそれを消費するために使用依存的です。システムを運ぶために、オリジナルの登録サービスは、常にで具体化されIServiceCollectionのコレクション、究極の依存性注入コンテナは、次のように具体化されたIServiceProviderのサードパーティの依存性注入フレームワークを統合したい場合は、オブジェクト内に来る、あなたはIServiceCollectionからセットを解決するためにそれらを使用する必要がありますIServiceProviderオブジェクト間の適応の問題。
一、IServiceCollection => ContainerBuilder => IServiceProvider
具体的には、我々はIServiceCollectionコレクションとIServiceProviderは、オブジェクト間のサードパーティの依存性注入フレームワークを設定することができますContainerBuilderのオブジェクトを。レッツ使用IServiceCollectionコレクションはContainerBuilderオブジェクトを作成するには、その後、IServiceProviderは、オブジェクトの使用に依存としてコンテナにオブジェクトを構築するために、元の登録サービスが含まれています。
二、IServiceProviderFactory <TContainerBuilder>
二使用して上に示した変換IServiceProviderFactory <TContainerBuilder>が完成したオブジェクト。次のコード断片、IServiceProviderFactory <TContainerBuilder>インターフェイス定義の二つの方法であって、前記CreateBuilderの IServiceCollection ContainerBuilderに対応するオブジェクトを作成し、指定されたコレクションの使用方法CreateServiceProviderの方法はさらに、容器の依存関係を作成ContainerBuilderを使用してオブジェクトですIServiceProviderオブジェクト。
パブリック インターフェース IServiceProviderFactory <TContainerBuilder> { TContainerBuilder CreateBuilder(IServiceCollectionサービス)。 IServiceProvider CreateServiceProvider(TContainerBuilder containerBuilder)。 }
.NETコアキャリアシステムは、常に最終的な依存関係としてコンテナにオブジェクトを作成するために登録IServiceProviderFactory <TContainerBuilder> IServiceProviderサービスを使用します。デフォルトベアラは、次のように登録されているDefaultServiceProviderFactoryタイプ。次のコードに示すように、DefaultServiceProviderFactoryオブジェクトはBuildServiceProvider IServiceCollectionがIServiceProviderに対応するオブジェクトのセットを作成する方法を指定して直接呼び出します。
パブリック クラス DefaultServiceProviderFactory:IServiceProviderFactory <IServiceCollection> { パブリック DefaultServiceProviderFactory():この(ServiceProviderOptions.Default){} 公共 DefaultServiceProviderFactory(ServiceProviderOptionsオプション)=> _オプション= オプション。 公共 IServiceCollection CreateBuilder(IServiceCollectionサービス)=> サービス。 公共 IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder)=> containerBuilder.BuildServiceProvider(_options)。 }
第三に、サードパーティ製の依存性注入フレームワークを統合
より深い理解とIServiceProviderFactory <TContainerBuilder>登録サービス統合を使用するサードパーティの依存性注入フレームワークに読者を可能にするために、我々は特定の例を実証する必要があります。私たちは、「ある依存性注入フレームワークのミニバージョン依存性注入フレームワーク猫「のミニバージョン」という名前のディレクトリを作成し、その後、私たちはその実装タイプの統合を完了するために、特定のIServiceProviderFactory <TContainerBuilder>を提供します」。
私たちは、最初の名前の作成CatBuilderの対応ContainerBuilderようなタイプを。必要性を作成するためのサービスの範囲が関与しているので、我々はServiceScopeは、オブジェクトサービスの範囲を表しCatBuilderクラス、中に埋め込まれた独自の次の2つのタイプが実際には別のServiceScopeFactoryはオブジェクトを作成表しIServiceProviderオブジェクト型のパッケージで設定しました植物は、それが猫のオブジェクトのカプセル化です。
パブリック クラスCatBuilder { プライベート クラスServiceScope:IServiceScope { 公共 ServiceScope(IServiceProviderサービス・プロバイダ)=>のServiceProvider = サービス・プロバイダ。 公共 IServiceProviderのServiceProvider { 取得します。} 公共 のボイドのDispose()=>(のServiceProvider など IDisposableを)?.Dispose()。 } プライベート クラスServiceScopeFactory:IServiceScopeFactory { プライベート 読み取り専用猫_cat。 公共 ServiceScopeFactory(猫猫)=> _cat =ネコ; 公共 IServiceScope CreateScope()=> 新しいServiceScope(_cat)。 } }
オブジェクトがCatBuilder猫オブジェクトのパッケージであり、それは直接法BuildServiceProvider猫にこのオブジェクトを返し、容器内に提供されるような最終的に依存します。CatBuilderは、初期化時にIServiceScopeFactoryインタフェースのためのサービス登録を追加し、特定の登録は、現在の子のように猫のオブジェクトから作成ServiceScopeFactoryオブジェクトです。アセンブリの範囲内で登録されたホールセールサービスを実現するために、我々は登録CatBuilderする方法を定義します。
パブリック クラスCatBuilder { プライベート 読み取り専用猫_cat。 公共CatBuilder(猫の猫) { _cat = 猫。 _cat.Register <IServiceScopeFactory>(C => 新しいServiceScopeFactory(c.CreateChild())、Lifetime.Transient)。 } 公共 IServiceProvider BuildServiceProvider()=> _cat。 公共CatBuilder登録(アセンブリアセンブリ) { _cat.Register(アセンブリ)。 返す これを。 } ... }
CatServiceProviderFactoryの種類は次のとおりIServiceProviderFactory <CatBuilder>インターフェイスを実現しました。実装のCreateBuilder方法では、我々は猫のオブジェクトを作成し、サービスレジストリ(ServiceDescriptorオブジェクト)を指定IServiceCollectionコレクションは、互換性のあるサービス登録(てServiceRegistryオブジェクト)に猫が含まれており、猫が作成されたオブジェクトに適用されます。我々は最終的に、この猫のオブジェクトの利点が返さCatBuilderオブジェクトを作成してください。CreateServiceProviderがIServiceProviderオブジェクトを返し達成するための別の方法は、方法によって得られたCatBuilderオブジェクトCreateServiceProviderを呼び出します。
パブリック クラス CatServiceProviderFactory:IServiceProviderFactory <CatBuilder> { パブリックCatBuilder CreateBuilder(IServiceCollectionサービス) { VARの猫= 新しいキャット(); foreachの(VARのサービスにおけるサービス) { 場合(!service.ImplementationFactory = ヌル) { cat.Register(service.ServiceType、プロバイダ) => service.ImplementationFactory(プロバイダ)、service.Lifetime.AsCatLifetime()); } それ以外の 場合(service.ImplementationInstance!=NULL ) { cat.Register(service.ServiceType、service.ImplementationInstance)。 } 他 { cat.Register(service.ServiceType、service.ImplementationType、service.Lifetime.AsCatLifetime())。 } } を返す 新しいCatBuilder(猫)。 } 公共 IServiceProvider CreateServiceProvider(CatBuilder containerBuilder)=> containerBuilder.BuildServiceProvider(); }
我々は、特に変換はAで実装、モードの二種類のライフサイクルを完了するためにServiceDescriptorてServiceRegistry型、直接変換への登録サービス・タイプから移行するように猫は、一貫性のある表現のライフサイクルサービス.NETコアDI骨格を有しますAsCatLifetime拡張メソッド。
内部 静的 クラス拡張 { パブリック 静的寿命AsCatLifetime(このServiceLifetime寿命) { 戻り寿命スイッチ { ServiceLifetime.Scoped => Lifetime.Self、 ServiceLifetime.Singleton => Lifetime.Root、 _ => Lifetime.Transient、 }。 } }
次に、我々は依存関係としてコンテナにCatServiceProviderFactory IServiceProviderオブジェクトを作成する方法を示します。フー、バー、バズとQuxタイプはIQuxがQux型インタフェース対応MapToAttribute特性をマークIFoo、IBAR、IBazとIQux、インターフェイス登録されている対応を実現しており、次のように我々は、インターフェイスおよび対応する実装タイプを定義しますマッピングの間。サービスインスタンスのライフサイクルの猫制御を反映するために、我々は、彼らが同じ基本クラスBaseから派生してみましょう。基本実装IDisposableを、我々の出力は、コンストラクタで対応するテキストおよび処分は、対応するインスタンスが作成され、解放されたときに決定するための方法を実装しました。
パブリック インターフェースIFoo {} パブリック インターフェイスIBAR {} パブリック インターフェイスIBaz {} パブリック インターフェイスIQux {} パブリック インターフェイス IFoobar <T1、T2> {} パブリック クラスベース:IDisposableを { パブリックベース()=> Console.WriteLineを($ 」のインスタンス{メソッドGetType()名前}作成されます。」)。 公共 ボイド廃棄()=> Console.WriteLineを($は、" {メソッドGetType()名}のインスタンスが配置されています。" )。 } パブリック クラスはFoo:ベース、IFoo {} パブリック クラスバー:ベース、IBAR {} パブリック クラスバズ:ベース、IBaz {} [MapTo(typeof演算(IQux)、Lifetime.Root)] パブリック クラスQux:ベース、IQux {} パブリック クラス FOOBAR <T1、T2>:IFoobar <T1、T2> { パブリック IFooはFoo { GET 。} 公共 IBARバー{ 取得します。} 公共FOOBAR(IFooのFOO、IBARバー) { フー = FOO。 バーは = バー。 } }
次のデモプログラムでは、我々はServiceCollectionコレクションを作成し、3つの異なるライフサイクルモデルがIFoo、IBARとIBazインタフェースのためのサービスレジストリに追加されました。これによると、我々はServiceCollection CatServiceProviderFactoryオブジェクトのコレクションを作成し、対応するCatBuilderオブジェクトを作成するために、そのCreateBuilderメソッドを呼び出ししようとしています。私たちは、そのオブジェクトの登録方法CatBuilderが登録IQux / Quxのためのサービスを追加することを目指して現在のアセンブリ、バルクサービスのレジストリエントリを完了呼び出します。
クラスプログラム { 静的な 無効メイン() { VARのサービス= 新しいServiceCollection() .AddTransient <IFoo、フー> () .AddScoped <IBAR>(_ => 新しいバー()) .AddSingleton <IBaz>(新バズ()) ; VaRの工場= 新しいCatServiceProviderFactory(); VARビルダー= factory.CreateBuilder(サービス) .Register(Assembly.GetEntryAssembly()); VaRのコンテナ= factory.CreateServiceProvider(ビルダー)。 GetServices(); GetServices(); Console.WriteLineを(" \ nRootコンテナが配置されています。" ); (コンテナとして IDisposableを)?.Dispose()。 ボイドGetServices() { 使用(VARの範囲= container.CreateScope()) { Console.WriteLineを(" \ nServiceスコープが作成されます。" )。 VaRの子= scope.ServiceProvider。 child.GetService <IFoo> (); child.GetService<IBAR> (); child.GetService <IBaz> (); child.GetService <IQux> (); child.GetService <IFoo> (); child.GetService <IBAR> (); child.GetService <IBaz> (); child.GetService <IQux> (); Console.WriteLineを(" \ nServiceスコープが配置されています。" ); } } } }
CreateServiceProvider CatServiceProviderFactoryオブジェクトのメソッド呼び出しで依存としてコンテナにIServiceProviderオブジェクトを作成した後、我々は、ネイティブメソッドGetServices方法には2つの呼び出しを持っています。GetServicesは、サービスの範囲を作成し、サービスのサービス・インスタンスの二組を提供し、この範囲内IServiceProviderを使用する場合は、このメソッドIServiceProviderオブジェクトを使用します。IServiceProviderは、そのDisposeメソッドを呼び出すことにより、最終的なリリースであることCatServiceProviderFactoryによって作成されたオブジェクト。図4-16に示すコンソール結果にプログラム意志の出力を実行した後、出力はまったく同じサービスのライフサイクルとデモプログラムの具現を反映しています。
[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]:サードパーティの依存性注入アダプタフレーム