マイクロソフト延長について:依存性の注入は、多くのことを紹介しましたが、原則の実現を重視し、いくつかの特定の実装シナリオのほとんど。それは概念、原則および使用の包括的プレゼンテーションを準備コアの礎石DOTNETコアとして。
ここでは最初の部分の概念が導入されました。
1.コンセプト
プロジェクトのGitHubのアドレス:https://github.com/aspnet/Extensions/tree/master/src/DependencyInjection
Microsoft.Extensions.DependencyInjection
これは、依存関係反転原理のMicrosoftの実装です。ASP.NETコアの礎石として、DependencyInjection
プロジェクトのあらゆる側面を通じて、理解ASP.NETコアのために重要であるだけでなく、その使用と原則を習得するために、また、それがプロジェクトを提供するのに役立つために、他のプロジェクトの開発に適用するのに役立ちます開発効率と品質。
シーン1.1問題
ソフトウェア開発では、プロジェクトでは、多くの場合、異なるモジュール、モジュール間の依存関係の数を持っています。例えば、我々は単純化されたシナリオを考え、私たちはユーザーの三つのカテゴリーがあります。
-
AccountControllerは、ユーザインタフェースを提供します
-
UserServiceのは、ビジネスロジックのユーザー管理を提供します
-
ユーザー管理へのデータアクセスを提供するために、UserRepository、
AccountController
内部には必要UserService
ながら、ユーザーを管理するために、インスタンスをUserService
内部が必要に基づいてUserRepository
データアクセスを提供します。私たちは、それらの間の依存関係を呼び出します。また、表現AccountController
に依存UserService
し、UserService
頼りUserRepository
。依存性の注入は、私たちは私たちの依存関係の管理を達成するのを助けるための強力なツールです。
1.2依存関係逆転の原則DIP
依存関係反転原則は原則モジュールをデカップリングソフトウェアプロジェクトの理論的な基礎となるものです、よく知られた設計原理の一つです。
次のように定義された原則は以下のとおりです。
高レベルのモジュールは、低レベルのモジュールに依存してはならない、どちらも、抄録に依存しなければならないdetails.Detailsに依存してはならないabstractions.Abstractionsに依存しなければなりません。
翻訳:
-
高レベルのモジュールはどちらも抽象的に依存している必要があり、低レベルのモジュールに依存してはなりません
-
要旨は細部に頼るべきではありません
-
詳細は抽象依存すべき
依存関係逆転の原則の実現がない場合には、我々は、渡されたAccountController
自分自身でクラスnew
キーへの依存を作成するためにUserService
、オブジェクトのインスタンスを
パブリック クラスAccountController { プライベート 読み取り専用UserServiceの_userService。 パブリックAccountController(){ この ._userService = 新しいUserServiceの()。 } }
これは、2つのクラス間の密結合につながっている、AccountController
とUserService
それぞれ作成するために一緒にバインドされてAccountController
作成され、時間をUserService
オブジェクトインスタンスを、私たちはテストする必要がある場合はAccountController
、時間を考慮する必要がありますUserService
ように依存クラスレベルダウン、UserService
に依存しUserRepository
、プロジェクト内のクラスが一緒に結合さ緊密に分割することが難しく、結合されています。
依存性逆転の原則に基づいて、通常インタフェースを介して分離を検討してください。例えば、我々はサービスへのユーザ・インタフェースを定義できます。
パブリック インターフェースIUserService { }
顧客サービスは、インターフェイスを実装します
パブリック クラスUserServiceの:IUserService { }
ではAccountController
、クラス、変更は、使用するベースのインターフェイスとなりましたUserService
。
パブリック クラスAccountController { プライベート 読み取り専用IUserService _userService。 パブリックAccountController(){ この ._userService = 新しいUserServiceの()。 } }
一方でHomeController
内部の、我々はプログラミングをベースにインターフェースすることができますが、このアプローチは、ご自身で解決していないnew
取得するにはUserService
、問題のオブジェクトのインスタンスを。
コントロールのIoCの1.3反転
IoC
DIPは、達成するために、よく知られているデザインパターンです。
その核となるアイデアは、次のとおりです。オブジェクトのインスタンスを必要なときに、常に自分自身を通じ考慮しないnew
、オブジェクトを作成する依存オブジェクトを作成するプロセスを下に置くが、他の誰かに仕事を担当するためにオブジェクトを作成するために、我々は通常と呼ばれる人々にコンテナ(コンテナ)またはサービスプロバイダ(のServiceProvider) 、我々はこの以降を使用しServiceProvider
、それを参照するために、
このオブジェクトのインスタンスから必要なときServiceProvider
に取得します。
以下は、広く使用されているの概略図です。持参常に取り、しかしから、自分の摩耗となり、あなたが身に着けるために
制御の反転の導入 のServiceProvider私たちは、オブジェクトのインスタンスを取得するのに役立ちます。
1.4依存性注入DI(依存性の注入)
DIは、IoCのパターンの実装です。
「EJBのない1つのJ2EE開発に関する専門家1「第6章
二つの方法でのIoCを達成するための主な方法:依存のルックアップ、依存性注入(P128)
依存性の注入は、より望ましい方法です。(P130)
Martin Fowler氏のオリジナルのテキスト:
その結果、私たちは、このパターンのために、より具体的な名前が必要だと思います。制御の反転は、あまりにも一般的な用語であるため、人々はそれが混乱を見つけます。様々なのIoC支持者との議論の多くの結果として、我々は、名前の依存性注入に落ち着きました。
効果にその:
すでにのIoCと呼ばれる特定のモードを、存在するが、IOCはあまりにも広く、任意のIoCのフレームワークは、より明確に表意を可能にするために、正確な主張にそれをDIを使用することにしました。
DIの複数の実装がありますが、私たちは、マイクロソフトの拡張で依存性の注入マイクロソフトの公式を提供するために構築され、ここで提示しました。それは、実装でそれを達成するために、コア全体ASP.NETベースのコアのIoCです。同時に、我々はまた、依存関係反転原理のサポートを達成するために、他のプロジェクトで使用することができます。
2.依存性の注入基本的な概念
2.1サービスの説明コレクションServiceCollection
MicrosoftのDI実装、すべてのサービスはDIによって、後であなたができる、唯一のこのコレクションでは、一度登録する必要がサービス提供、収集サービス、コレクション全体のためのDI、唯一の共通の記述に登録する必要がありますユーザに提供します。
インターフェイスとして、コレクションを定義見ることができますが、実際に登録されたサービスのセットを保存するために使用されます。IServiceCollection
パブリック インターフェース IServiceCollection:のIList <ServiceDescriptor>、ICollectionを<ServiceDescriptor>、IEnumerableを<ServiceDescriptor> 、IEnumerableを { }
デフォルトでは、1組達成しているIServiceCollection
と呼ばれる実現のを。ASP.NETコアで、内部はオブジェクトのインスタンスを作成し、我々はまた、他のプロジェクトでは、独自の、非常にシンプルな、ストレート作成することができて準備のために使用します。ServiceCollection
new
IServiceCollectionサービス= 新しい ServiceCollection();
2.2サービスのサービス
DIの文脈において、特にサービスオブジェクトインスタンスのDIコンテナ管理による。このサービスは、**サービスと呼ばれている必要はありませんが、DIによって管理される任意のオブジェクトにすることができ、DIは唯一、この文脈において、我々は総称サービスと呼ぶことにしますさ。
サービスは、先に述べたように、私たち自身の定義であるAccountController
とUserService
ように。
私たちは、複雑なオブジェクトの依存関係を存在するため、DIはまたこれらのインスタンス間の依存関係を管理し、例えば、DIによるライフサイクルマネジメントサービスオブジェクトにサービスを提供するために取得します。
最初のDIを使用するために登録しなければならないサービスは、しかし、事前登録や決定は、サービスのライフサイクルを考慮する必要があります。
2.3ライフサイクルサービス
サービスオブジェクトのインスタンスは、ライフサイクルのさまざまな種類があります。アプリケーションはのみ、アプリケーションの終了時に解放されるように、起動時に同じアプリケーションを持つオブジェクトのライフサイクルのいくつかは、作成しました。例えば、私たちのデータアクセスオブジェクトインスタンス。メソッド呼び出しの終了後にのみ、現在の方法で使用される一部のオブジェクトは、破棄されなければなりません。これらのニーズを管理するために使用されるライフサイクル管理サービス。
DIは、ライフサイクルの3種類をサポートしています。
-
シングルトン、シングルトン、現在のアプリケーション環境で唯一のインスタンス。そのようなデータアクセスオブジェクトインスタンスなどのサービス。
-
スコープ、限られた範囲では、かつてこの範囲の外に、サービスオブジェクトのこの範囲で破壊する必要があります。たとえば、Web開発要求オブジェクトインスタンス。
-
過渡、過渡、1回使用、DIから得られたそれぞれは、新しいインスタンスを返します。
Microsoft.Extensions.DependencyInjection.ServiceLifetime
パブリック 列挙ServiceLifetime { シングルトン、 スコープ、 過渡 }
ライフサイクルサービスは、登録サービスの時に決定されます。使用時には、インスタンスへの直接アクセスは、もはやライフサイクルサービスを指定されません。マイクロソフトは、登録サービスのライフサイクルに指定されたサービスの拡大を促進するためのさまざまな方法を提供しています。ここでは、例えば、ライフサイクルは、実施の形態の一つの一般的な方法で指定されています。
// ベースのインタフェースレジスタ services.AddSingleton <IUserService、UserServiceの>() ;
2.4サービスプロバイダのServiceProvider
オブジェクトインスタンスの登録サービスのセットから必要なときにサービスを利用し得るが、サービスプロバイダを介して取得する必要がない、サービスプロバイダは、登録されたサービスのセットから明確な必要性です。定義されたサービス・プロバイダ・インターフェースは、DIフレームワークで定義されていない、.NETの基本的な定義の一つです。IServiceProvider
パブリック インターフェイスIServiceProvider { オブジェクトのgetService(タイプのServiceType)。 }
DIは、拡張のServiceProviderを取得するために、サービスプロバイダのサポートを提供します。ServiceCollectionContainerBuilderExtensions
IServiceCollection
パブリック 静的のServiceProvider BuildServiceProvider(このIServiceCollectionサービス) { 戻りBuildServiceProvider(サービス、ServiceProviderOptions.Default)を、 }
だから、我々は通常入手し、それを使用するには、このメソッドを使用します。
// 登録サービスコンテナの作成 IServiceCollectionサービス= 新しい新ServiceCollection(); // 登録サービスを、ここで指定された単一の実施形態 services.AddSingleton <IUserService、UserServiceの> (); // 血管を介してサービスプロバイダを取得 IServiceProviderプロバイダ= services.BuildServiceProvider ();
サービスへ2.5オブジェクトインスタンスへのアクセス
サービスプロバイダによってサービスマニュアルオブジェクトのインスタンスを取得します。サービス登録の種類によって、直接呼び出しGetService
方法がすることができます。
例えば、私たちの前に、サービスの種類にサインアップしIUserService
ている実装タイプUserService
、あなたはこのタイプによって、このインタフェースを実装するオブジェクトの実際のインスタンスを取得することができます。
// 登録サービスコンテナの作成 IServiceCollectionサービス= 新しい新ServiceCollection(); // 登録サービスを、ここで指定された単一の実施形態 services.AddSingleton <IUserService、UserServiceの> (); // 血管を介してサービスプロバイダを取得 IServiceProviderプロバイダを= services.BuildServiceProvider (); // インターフェイスインスタンスを介してサービスオブジェクトを取得 IUserServiceインスタンス= provider.GetService <IUserService>( );
これは、より複雑なようです。実際の使用では、我々はめったに後、私たちはそれ以上の特定の使用を行く、DIを使用するような方法を使用していません。