IServiceProviderについての最初の話
IServiceProviderは、次のようにIOCは、オブジェクトを見つける持っている必要があります想像し、種類に応じて、機能のオブジェクトを取得します
パブリックインターフェイスIServiceProvider { オブジェクトのgetService(タイプのServiceType)。 }
ServiceProviderについての話
ServiceProviderはIServiceProviderをインスタンス、のgetServiceは、容器内の実際のオブジェクトを得るために、達成されるが、次のように、(このインタフェースは再度後述する)IServiceProviderEngineによるものです。
パブリックオブジェクトのgetService(タイプのServiceType) { リターンthis._engine.GetService(サービス種別)。 }
また、返されるオブジェクトのタイプは、のServiceProvider方法ServiceCollection BuildServiceProvider(クラスServiceCollectionContainerBuilderExtensions存在)があるれています
/// <要約> <:/ CREFを参照= "Microsoft.Extensions.DependencyInjection.IServiceCollection T">から</参照CREF = "Microsoft.Extensions.DependencyInjection.ServiceProvider T">構築するため///拡張メソッド。 /// </要約> パブリック静的クラスServiceCollectionContainerBuilderExtensions { /// <要約> ///作成<参照CREF = "T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />提供からサービスを含む<参照CREF =」 T:Microsoft.Extensions.DependencyInjection.IServiceCollection」/>。 /// </要約> ///ます。<param name = "サービス"> <CREFを参照してください= "T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> /// <戻る> <CREF = "T:Microsoft.Extensions.DependencyInjection.ServiceProvider"を参照/>.</戻る> { 戻りservices.BuildServiceProvider(ServiceProviderOptions.Default)を、 } /// <要約> ///が作成/:設けからサービスを含む<参照CREF = "T Microsoft.Extensions.DependencyInjection.ServiceProvider" /> <CREF = "Microsoft.Extensions.DependencyInjection.IServiceCollection T"を参照してください。 > /// optionalyスコープの検証を可能にします。 /// </要約> ///ます。<param name = "サービス"> <参照CREF = "T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />サービス記述子を含む</ param>の。 ///の<paramの名前=」 /// <C>真</ c>をチェックを実行するには、スコープのサービスがルート・プロバイダから解決されることは決してありませんことを検証します。そうでない場合は、<C>偽</ C>。 /// </ param>の /// <戻る> <CREF = "T:Microsoft.Extensions.DependencyInjection.ServiceProvider"を参照/>.</戻る> パブリック静的のServiceProvider BuildServiceProvider( このIServiceCollectionサービス、 BOOL validateScopes) { 戻りservices.BuildServiceProvider(新しいServiceProviderOptionsを( ) { validateScopes = validateScopes })。 } /// <要約> ///が作成/:設けからサービスを含む<参照CREF = "T Microsoft.Extensions.DependencyInjection.ServiceProvider" /> <CREF = "Microsoft.Extensions.DependencyInjection.IServiceCollection T"を参照してください。 > /// optionalyスコープの検証を可能にします。 /// </要約> /// <PARAM NAME = "サービス"> <参照CREF = "T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />サービス記述子を含む</ param>の。 /// <PARAM NAME = "オプション"> // /設定し、さまざまなサービスプロバイダーの行動。 /// </ PARAM> /// <戻る> <CREF =見る"T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />.</戻る> パブリック静的のServiceProvider BuildServiceProvider( このIServiceCollectionサービス、 ServiceProviderOptionsオプション) { もし(サービス== nullの) 新しい例外ArgumentNullExceptionスロー(がNameOf(サービスを)); ((IEnumerableを<ServiceDescriptor>)のサービス、オプション)新しいのServiceProviderを返します。 } }
約IServiceProviderEngine、ServiceProviderEngineと組み合わされなければならないし、特定のServiceProviderの知っている対象がIOCコンテナのオブジェクトを取得する方法であるServiceProviderEngineScope
使用している場合BuildServiceProviderは最終的に呼び出します((IEnumerableを<ServiceDescriptor>)サービス、オプション)新しい新しいのServiceProviderを、そして、それは次の関数を呼び出すことです。
内部のServiceProvider( IEnumerableを<ServiceDescriptor> serviceDescriptors、 ServiceProviderOptionsオプション) { IServiceProviderEngineCallbackコールバック=(IServiceProviderEngineCallback)ヌル。 IF(options.ValidateScopes) { コールバック=(IServiceProviderEngineCallback)この; this._callSiteValidator =新しいCallSiteValidator(); } スイッチ(options.Mode) { ケースServiceProviderMode.Dynamic: this._engine =(IServiceProviderEngine)新しいDynamicServiceProviderEngine(serviceDescriptors、コールバック)。 ブレーク; ケースServiceProviderMode.Runtime: this._engine =(IServiceProviderEngine)新しいRuntimeServiceProviderEngine(serviceDescriptors、コールバック); ブレーク; ケースServiceProviderMode.Expressions: this._engine =(IServiceProviderEngine)新しいExpressionsServiceProviderEngine(serviceDescriptors、コールバック)。 ブレーク; ケースServiceProviderMode.ILEmit: this._engine =(IServiceProviderEngine)新しいILEmitServiceProviderEngine(serviceDescriptors、コールバック)。 ブレーク; デフォルト: スロー新しい非サポート例外(「モード」)。 } }
それは、最終的には今簡単な例をDynamicServiceProviderEngineあるもののServiceProviderMode ServiceProviderEngine例を必要に応じて決定されます。DynamicServiceProviderEngine最終的に継承ServiceProviderEngine、
getService上記のように、実際のgetServiceのServiceProviderEngineと呼ばれています
パブリックオブジェクトのgetService(タイプのServiceType) { リターンthis.GetService(サービス種別、this.Root)。 }
ServiceProviderScopeインスタンス化されThis.Root。上記this.GetService(サービス種別、this.Root)は、次の関数を呼び出します。
内部オブジェクトのgetService( タイプのServiceType、 ServiceProviderEngineScope serviceProviderEngineScope) { IF(this._disposed) ThrowHelper.ThrowObjectDisposedException(); FUNC <ServiceProviderEngineScope、オブジェクト> orAdd = this.RealizedServices.GetOrAdd(サービス種別、this._createServiceAccessor)。 this._callback .OnResolve(サービス種別、(IServiceScope)serviceProviderEngineScope);? ServiceProviderEngineScope providerEngineScope = serviceProviderEngineScope。 リターンorAdd(providerEngineScope)。 }
最終的なコールがあるのFunc <ServiceProviderEngineScope、オブジェクト> orAdd = this.RealizedServices.GetOrAdd(サービス種別、this._createServiceAccessor); RealizedServicesであることを特徴とする請求ConcurrentDictionary <{GET;}のFunc <ServiceProviderEngineScope、オブジェクト>> RealizedServicesタイプ、this._createServiceAccessorであるのFunc < ServiceProviderEngineScopeは、オブジェクト> がある場合、その後、あなたは辞書からサービスを受ける、あるServiceProviderEngineScopeに基づいて、オブジェクトの最終買収、の委託により、そこにキューに追加し、直接返却されます。さらにServiceProviderEngineがインスタンスインスタンス化this._createServiceAccessor =新規のFunc <タイプ、のFunc <ServiceProviderEngineScope、オブジェクト>>(this.CreateServiceAccessor)を、 CreateServiceAccessorは、以下のように定義された関数です。
民間のFunc <ServiceProviderEngineScope、オブジェクト> CreateServiceAccessor( タイプのServiceType) { IServiceCallSite呼び出し場所= this.CallSiteFactory.CreateCallSite(サービス種別、新しいCallSiteChain())。 IF(呼び出し場所== NULL) リターン(機能<ServiceProviderEngineScope、オブジェクト>)(_ =>(オブジェクト)NULL); ?this._callback .OnCreate(呼び出し場所)。 リターンthis.RealizeService(呼び出し場所)。 }
次のようにDynamicServiceProviderEngine用語で、RealizeServiceが定義されています。
保護オーバーライドのFunc <ServiceProviderEngineScope、オブジェクト> RealizeService( IServiceCallSite呼び出し場所) { int型callCount = 0。 リターン(機能<ServiceProviderEngineScope、オブジェクト>)(範囲=> { IF(Interlocked.Increment(REF callCount)== 2) Task.Run <のFunc <ServiceProviderEngineScope、オブジェクト>>((機能<のFunc <ServiceProviderEngineScope、オブジェクト>>) (()=> base.RealizeService(呼び出し場所))); 戻りthis.RuntimeResolver.Resolve(呼び出し場所、範囲); }); }
RuntimeResolverはServiceProviderEngineのプロパティです。これまでのところ、データIOCコンテナはに得ることができます。次のブログはthis.RuntimeResover.Resolveで物事を説明していきます。