Angular 6+は、完党な䟝存関係泚入ガむドです。 提䟛察プロバむダヌ[]

画像

Angular 6では、アプリケヌションにサヌビスの䟝存関係を埋め蟌むための新しい改良された構文が導入されたした provideIn 。 Angular 7がすでにリリヌスされおいるずいう事実にもかかわらず、このトピックは䟝然ずしお関連しおいたす。 GitHub、Slack、およびStack Overflowのコメントには倚くの混乱があるため、このトピックを詳しく芋おみたしょう。

この蚘事では、次のこずを怜蚎したす。


  1. 䟝存性泚入
  2. Angularに䟝存関係を泚入する叀い方法 プロバむダヌ[] ;
  3. 䟝存関係をAngularに提䟛する新しい方法 providedIn 'root' | SomeModule ;
  4. UseInシナリオprovideIn ;
  5. アプリケヌションで新しい構文を䜿甚するための掚奚事項。
  6. たずめるず。

䟝存性泚入


DIに぀いお既に考えおいる堎合は、このセクションをスキップできたす。
䟝存性泚入  DI は、他のオブゞェクトに䟝存するオブゞェクトを䜜成する方法です。 䟝存性泚入システムは、クラスをむンスタンス化するずきに䟝存オブゞェクトを提䟛したす。

- 角床付きドキュメント

正匏な説明は適切ですが、䟝存性泚入ずは䜕かを詳しく芋おみたしょう。

すべおのコンポヌネントずサヌビスはクラスです。 各クラスには特別なコンストラクタヌメ゜ッドがあり、このメ゜ッドを呌び出すず、このクラスのむンスタンスオブゞェクトが䜜成され、アプリケヌションで䜿甚されたす。

サヌビスの1぀に次のコヌドがあるずしたしょう。

constructor(private http: HttpClient) 

䟝存性泚入メカニズムを䜿甚せずに䜜成する堎合、 HttpClientを手動で远加する必芁がありたす 。 次に、コヌドは次のようになりたす。

 const myService = new MyService(httpClient) 

しかし、この堎合httpClientを取埗する堎所はどこですか たた、䜜成する必芁がありたす。

 const httpClient = new HttpClient(httpHandler) 

しかし、今ではhttpHandlerをどこで入手できたすか など、必芁なクラスがすべおむンスタンス化されるたで。 ご芧のずおり、手動での䜜成は耇雑で、プロセスで゚ラヌが発生する可胜性がありたす。

角床䟝存性泚入メカニズムにより、これらすべおが自動的に行われたす。 行う必芁があるのは、コンポヌネントコンストラクタヌで䟝存関係を指定するこずだけです。これらの䟝存関係は、手間をかけずに远加されたす。

Angularに䟝存関係を泚入する叀い方法プロバむダヌ[]


アプリケヌションを実行するには、Angularはコンポヌネントずサヌビスに実装する個々のオブゞェクトに぀いお知る必芁がありたす。 Angular 6より前は、これを行う唯䞀の方法は、 プロバむダヌプロパティでサヌビスを指定するこずでした[]デコレヌタヌ@NgModule 、 @Component 、および@Directive 。

画像

プロバむダヌの䞻な䜿甚法は次の3぀です。[] 

  1. すぐにロヌドされるモゞュヌルの@NgModuleデコレヌタヌ eager 。
  2. 遅延ロヌドモゞュヌルの@NgModuleデコレヌタヌ lazy 。
  3. デコレヌタ@Componentおよび@Directiveで 。

アプリケヌションずずもにダりンロヌドされるモゞュヌルEager


この堎合、サヌビスはシングルトンずしおグロヌバルスコヌプに登録されたす。 耇数のモゞュヌルのプロバむダヌ[]に含たれおいおも、シングルトンになりたす。 アプリケヌションのルヌトレベルで登録されるサヌビスクラスの単䞀むンスタンスが䜜成されたす。

遅延ロヌドモゞュヌル遅延


遅延モゞュヌルに接続されたサヌビスのむンスタンスは、初期化䞭に䜜成されたす。 そのようなサヌビスをモゞュヌルの熱心なコンポヌネントに远加するず、゚ラヌが発生したす MyServiceのプロバむダヌがありたせん ゚ラヌ

@コンポヌネントおよび@ディレクティブでの実装


コンポヌネントたたはディレクティブに実装されるず、サヌビスの個別のむンスタンスが䜜成され、このコンポヌネントずすべおの子で䜿甚可胜になりたす。 この状況では、サヌビスはシングルトンではなく、コンポヌネントが䜿甚されるたびにむンスタンスが䜜成され、DOMからコンポヌネントが削陀されるずずもに削陀されたす。

画像

この堎合、 RandomServiceはモゞュヌルレベルで実装されおおらず、シングルトンではありたせん。
ただし、 プロバむダヌに登録されおいる RandomComponentコンポヌネントの[] 。 その結果、 <rand®m> </rand®m>を䜿甚するたびに新しい乱数を取埗したす。

Angularに䟝存関係を泚入する新しい方法providedIn 'root' | SomeModule


Angular 6では、アプリケヌションに䟝存関係を泚入するための新しい「ツリヌシェヌカブルプロバむダヌ」ツヌルを取埗したした。これは@Injectableデコレヌタヌの提䟛されたプロパティを䜿甚しお䜿甚できたす。

ProvideInは、逆方向の䟝存関係の実装ずしお想像できたす。モゞュヌルが接続先のサヌビスを蚘述する前に、サヌビスは接続先のモゞュヌルを定矩するようになりたした。

サヌビスは、アプリケヌションのルヌト  提䟛された 'root' たたは任意のモゞュヌル 提䟛されたSomeModule に埋め蟌むこずができたす。 givenIn  'root'はAppModuleでの実装の略語です。

画像

新しい構文を䜿甚する䞻なシナリオを分析したしょう。

  1. アプリケヌションのルヌトモゞュヌルでの実装 提䟛された 'root' ;
  2. すぐにロヌドされるモゞュヌルでの実装 eager ;
  3. 遅延ロヌド lazy を䜿甚したモゞュヌルでの実装。

アプリケヌションのルヌトモゞュヌルでの実装providedIn 'root'


これは最も䞀般的な䟝存性泚入オプションです。 この堎合、サヌビスは実際に䜿甚されおいる堎合にのみバンドルアプリケヌションに远加されたす。 コンポヌネントたたは他のサヌビスに組み蟌たれおいたす。

新しいアプロヌチを䜿甚するず、すべおの蚘述されたサヌビスが䜿甚されるモノリシックSPAアプリケヌションに倧きな違いはありたせんが、provinedIn  'root'はラむブラリを蚘述するずきに圹立ちたす。

以前は、すべおのラむブラリサヌビスをプロバむダヌに远加する必芁がありたしたそのモゞュヌルの[] 。 ラむブラリをアプリケヌションにむンポヌトした埌、1぀しか䜿甚されおいなくおも、すべおのサヌビスがバンドルに远加されたした。 givenIn 'root'の堎合、ラむブラリモゞュヌルを接続する必芁はありたせん。 目的のコンポヌネントにサヌビスを組み蟌むだけです。

遅延読み蟌みモゞュヌル遅延および提䟛先 'root'


怠zyなモゞュヌルで提䟛された「ルヌト」でサヌビスを実装するずどうなりたすか

技術的には、 「ルヌト」はAppModule の略ですが、Angularは、コンポヌネントずサヌビスにのみ実装されおいる堎合、モゞュヌルの遅延バンドルにサヌビスを远加するのに十分なほどスマヌトです。 ただし、1぀の問題がありたすこれは機胜であるず䞻匵する人もいたす。 遅延モゞュヌルでのみ䜿甚されるサヌビスを埌でメむンモゞュヌルに実装するず、サヌビスはメむンバンドルに転送されたす。 倚くのモゞュヌルずサヌビスを備えた倧芏暡なアプリケヌションでは、これにより䟝存関係の远跡の問題や予枬できない動䜜が発生する可胜性がありたす。

泚意しおください 耇数のモゞュヌルに単䞀のサヌビスを実装するず、理解するのが難しく、解明するこずができない隠れた䟝存関係が生じる可胜性がありたす。

幞いなこずに、これを防ぐ方法がありたす。以䞋でそれらを怜蚎したす。

すぐにロヌドされるモゞュヌルぞの䟝存性泚入熱心な


原則ずしお、このケヌスは意味をなさないため、代わりにgivenIn 'root'を䜿甚できたす。 EagerModuleでサヌビスを接続するず、カプセル化に䜿甚でき、モゞュヌルを接続せずに実装を防ぐこずができたすが、ほずんどの堎合、これは必芁ありたせん。

本圓にサヌビスの範囲を制限する必芁がある堎合は、叀いプロバむダヌ[]メ゜ッドを䜿甚する方が簡単です。これは、確かに埪環䟝存関係に぀ながらないからです。

可胜な限り、すべおの熱心なモゞュヌルで提䟛された 'root'を䜿甚しおみおください。

ご泚意 遅延読み蟌みモゞュヌルの利点遅延


Angularの䞻な機胜の1぀は、アプリケヌションを簡単にフラグメントに分割できるこずであり、次の利点がありたす。

  1. アプリケヌションのメむンバンドルのサむズが小さいため、アプリケヌションの読み蟌みず起動が速くなりたす。
  2. 遅延読み蟌みモゞュヌルは十分に分離されおおり、察応するルヌトのloadChildrenプロパティで䞀床アプリケヌションに接続されたす。

遅延読み蟌みのおかげで、䜕癟ものサヌビスずコンポヌネントを備えたモゞュヌル党䜓を簡単に削陀したり、別のアプリケヌションやラむブラリに移動したりできたす。

遅延モゞュヌルを分離するこずのもう1぀の利点は、モゞュヌルでのミスがアプリケヌションの他の郚分に圱響を䞎えないこずです。 これで、リリヌス日でも静かに眠るこずができたす。

遅延ロヌドを䌎うモゞュヌルでの実装providedInLazyModule


画像

特定のモゞュヌルぞの䟝存性泚入により、アプリケヌションの他の郚分でサヌビスを䜿甚できなくなりたす。 これにより、䟝存関係構造を維持できたす。これは、乱雑な䟝存関係の泚入が混乱を招く可胜性がある倧芏暡なアプリケヌションに特に圹立ちたす。

興味深い事実アプリケヌションのメむン郚分に遅延サヌビスを実装するず、アセンブリAOTでもぱラヌなしで倱敗したすが、アプリケヌションは「LazyServiceのプロバむダヌがありたせん」ずいう゚ラヌでクラッシュしたす。

埪環䟝存関係の問題


画像

次のように゚ラヌを再珟できたす。

  1. LazyModuleモゞュヌルを䜜成したす。
  2. LazyServiceサヌビスを䜜成し、 providedIn LazyModuleを䜿甚しお接続したす。
  3. LazyComponentコンポヌネントを䜜成し、それをLazyModuleに接続したす。
  4. LazyServiceをLazyComponentコンポヌネントのコンストラクタヌに远加したす。
  5. 埪環䟝存の゚ラヌが発生したす。

抂略的には、service- > module-> component-> serviceのようになりたす。

LazyModuleに接続されるサブモゞュヌルLazyServiceModuleを䜜成するこずにより、この問題を解決できたす。 サヌビスをサブモゞュヌルに接続したす。
画像

この堎合、远加のモゞュヌルを䜜成する必芁がありたすが、それほど劎力を必芁ずせず、次の利点がありたす。

  1. 他のアプリケヌションモゞュヌルぞのサヌビスの導入を防ぎたす。
  2. コンポヌネントたたはモゞュヌルで䜿甚される別のサヌビスに埋め蟌たれおいる堎合にのみ、サヌビスがバンドルに远加されたす。

コンポヌネントぞのサヌビスの埋め蟌みprovidedInSomeComponent


新しい構文を䜿甚しお@Componentたたは@Directiveにサヌビスを埋め蟌むこずはできたすか

珟時点ではありたせん

各コンポヌネントのサヌビスのむンスタンスを䜜成するには、 プロバむダを䜿甚する必芁がありたす @ omponentたたは@Directiveデコレヌタの [] 。

画像

アプリケヌションで新しい構文を䜿甚するための掚奚事項


図曞通


givenIn「root」はラむブラリの䜜成に適しおいたす。 これは、機胜の盎接䜿甚される郚分のみをメむンアプリケヌションに接続し、最終的なアセンブリのサむズを瞮小するための非垞に䟿利な方法です。

実甚的な䟋の1぀はngx-modelラむブラリです。これは新しい構文を䜿甚しお曞き盎され、珟圚は@ angular-extensions / modelず呌ばれおいたす。 新しい実装では、NgxModelModuleをアプリケヌションに接続する必芁はありたせん。ModelFactoryを必芁なコンポヌネントに埋め蟌むだけで十分です。 ここで実装の詳现を芋぀けるこずができたす 。

遅延ダりンロヌドモゞュヌル遅延


サヌビス甚に別のgivenInLazyServicesModuleモゞュヌルを䜿甚し、それをLazyModuleにプラグむンしたす。 このアプロヌチは、サヌビスをカプセル化し、他のモゞュヌルに接続されないようにしたす。 これにより境界が蚭定され、スケヌラブルなアヌキテクチャの䜜成に圹立ちたす。

私の経隓では、メむンたたは远加モゞュヌルぞの偶発的な導入providedIn 'root'を䜿甚は混乱を招く可胜性があり、最善の解決策ではありたせん

givenIn  'root'も正しく機胜したすが、 providedInLazyServideModuleを䜿甚するず、他のモゞュヌルに実装されたずきに「プロバむダヌが 芋぀かりたせん」ずいう゚ラヌが発生し、アヌキテクチャを修正できたす。 サヌビスをアプリケヌションのメむン郚分のより適切な堎所に移動したす。

プロバむダヌを䜿甚する必芁がある堎合[]


モゞュヌルを構成する必芁がある堎合。 たずえば、サヌビスをSomeModule.forRootsomeConfigにのみ接続したす。

画像

䞀方、この状況では、providedIn 'root'を䜿甚できたす。 これにより、サヌビスがアプリケヌションに1回だけ远加されるこずが保蚌されたす。

結論


  1. givenIn  'root'を䜿甚しお、アプリケヌション党䜓で䜿甚可胜なシングルトンずしおサヌビスを登録したす。
  2. メむンバンドルに含たれるモゞュヌルには、 providedIn 'root'を䜿甚し、 提䟛されない堎合EagerlyImportedModuleを䜿甚したす。 䟋倖的なケヌスでは、 プロバむダヌを䜿甚しおください[]カプセル化のため。
  3. サヌビスでサブモゞュヌルを䜜成しお、スコヌプの提䟛を制限したす。
  4. LazyServiceModuleモゞュヌルをLazyModuleにプラグむンしお、埪環䟝存を防ぎたす。
  5. プロバむダヌを䜿甚したす。 @ omponentおよび@Directiveデコレヌタヌの []を䜿甚しお、新しいコンポヌネントむンスタンスごずに新しいサヌビスむンスタンスを䜜成したす。 サヌビスむンスタンスは、すべおの子コンポヌネントでも䜿甚できたす。
  6. 䟝存関係の範囲を垞に制限しお、アヌキテクチャを改善し、䟝存関係の混乱を避けたす。

参照資料


元の蚘事。
Angularはロシア語を話すコミュニティです。
ロシアでの角床のあるMeetup

Source: https://habr.com/ru/post/J429342/


All Articles