Angular 6でサービスを生成するときにInjectableデコレーターを提供する目的は何ですか?


136

Angular CLIでサービスを生成する場合、Injectableデコレーターのデフォルトの「root」を使用して、「provided in」プロパティーで追加のメタデータを追加します。

@Injectable({
  providedIn: 'root',
})

正確には提供されますか?これにより、サービスがアプリケーション全体で「グローバル」タイプのシングルトンサービスのように利用可能になると想定していますが、AppModuleのプロバイダー配列でそのようなサービスを宣言する方がきれいではありませんか?

更新:

他の誰にとっても、特に機能モジュールのみにサービスを提供したい場合は、次の段落でそれについて別の良い説明が提供されました。

@Injectable()新しいprovidedIn 属性を使用して、デコレーター内でプロバイダーを直接登録するための新しい推奨される方法があります。'root'アプリケーションの値または任意のモジュールとして受け入れます。を使用'root'するinjectableと、アプリケーションでシングルトンとして登録され、ルートモジュールのプロバイダーに追加する必要はありません。あなたが使用している場合は同様に、 providedIn: UsersModuleinjectableのプロバイダとして登録されているUsersModuleにそれを追加することなく、providersモジュールの「 - 。 https://blog.ninja-squad.com/2018/05/04/what-is-new-angular -6 /

更新2:

さらに調査した後、 providedIn: 'root'

provideルートモジュール以外のモジュールでサービスを利用したい場合providersは、機能モジュールのデコレーターで配列を使用することをお勧めします。そうしないと、循環依存関係に悩まされることになります。ここで行われる興味深い議論-https://github.com/angular/angular-cli/issues/10170


17
あなたの更新は、質問に追加するのではなく、答え(あなた自身の質問に答えることができます)であるべきだと思います。
PhoneixS 2018

最も重要な部分はSINGLETONです。誰も言及していません。
カイルバーケット

回答:


54

ProvidedInを使用する場合、注射はモジュールのプロバイダーに追加されずに、モジュールのプロバイダーとして登録されます。

から Docs

サービス自体は、CLIが生成したクラスであり、@ Injectableで装飾されています。デフォルトでは、このデコレーターは、サービスのプロバイダーを作成するprovidedInプロパティーで構成されています。この場合、providedIn: 'root'は、サービスをルートインジェクターで提供する必要があることを指定します。


4
Sajeetharanに感謝します。さて、サービスを提供する場所を指定する新しいショートカット方法のようです。私の最初の好みは、ProvidedInタグの散在するコードベースを熟読するのではなく、モジュールのプロバイダーリストを見てプロバイダーとして宣言されたすべてのサービスを確認することだったと思います...(?)
Stefan Zvonar

2
Angularがこれを追加する理由はありましたか?これが解決している問題はありますか?これには理由がありません。
prolink007 2018

3
AppModule / CoreModuleの定義を少し小さくします;)
Stefan Zvonar

22
@ prolink007。providedInを使用すると、サービスをアプリで遅延ロードできます。これをテストするには、コンソールログをサービスに配置します。私のホームページは16個のサービスをロードするために使用されていましたが、現在は9個をロードしています。
Stevethemacguy

3
providedIn属性を使用してサービスをツリーシェイク可能にするには、@Injectable()デコレータを使用するときにサービスを初期化する場所を定義します。次に、NgModule宣言のproviders属性とそのimport文からそれを削除する必要があります。これにより、バンドルから未使用のコードを削除して、バンドルサイズを削減できます。
nircraft、

48

providedIn: 'root' Angular 6以降、サービスを提供する最も簡単で効率的な方法です:

  1. このサービスは、アプリケーションのシングルトンとして利用でき、モジュールのプロバイダー配列(Angular <= 5など)に追加する必要はありません。
  2. サービスが遅延ロードされたモジュール内でのみ使用される場合、そのモジュールで遅延ロードされます
  3. 使用されない場合は、ビルドに含まれません(ツリーシェイク)。

詳細については、ドキュメントNgModule FAQを読むことを検討してください

ところで:

  1. アプリケーション全体のシングルトンが必要ない場合は、代わりにプロバイダのコンポーネント配列を使用してください。
  2. スコープを制限して、他の開発者が特定のモジュールの外部でサービスを使用しないようにする場合は、providers代わりにNgModule の配列を使用します。

37

ドキュメントから

注射可能なデコレータとは何ですか?

クラスをInjectorで作成できるようにマークします。

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

サービス自体は、CLIが生成したクラスであり、@ Injectable()で装飾されています。

正確には提供されますか?

@NgModuleまたは他のInjectorTypeに関連付けるか、このインジェクタブルを「ルート」インジェクタに提供するように指定することにより、インジェクタブルを提供するインジェクタを決定します。

providedIn: Type<any> | 'root' | null

providedIn: 'root'

ルートレベルでサービスを提供すると、Angularはサービスの単一の共有インスタンスを作成し、それを要求するすべてのクラスに注入します。@Injectable()メタデータにプロバイダーを登録すると、Angularは、コンパイルされたアプリが使用されていない場合は、サービスを削除してアプリを最適化することもできます。

providedIn:モジュール

特定の@NgModuleでサービスを提供するように指定することもできます。たとえば、アプリケーションが作成したモジュールをインポートしない限り、サービスがアプリケーションで利用できないようにするには、サービスをモジュールで提供するように指定できます。

import { Injectable } from '@angular/core';
import { UserModule } from './user.module';

@Injectable({
  providedIn: UserModule,
})
export class UserService {
}

このメソッドは、何も注入しない場合にサービスのツリーシェイク(ツリーシェイクは未使用のコードをコードベースから削除するビルドプロセスのステップ)を有効にするため、推奨されます。

サービスで提供するモジュールを指定できない場合は、モジュール内でサービスのプロバイダーを宣言することもできます。

import { NgModule } from '@angular/core';
import { UserService } from './user.service';

@NgModule({
  providers: [UserService],
})
export class UserModule {
}

4
最高の説明。
NOP

2
この答えは、角度付きドキュメントの定義よりも優れています。非常に明確な。
Shameera Anuranga

2
非常によく説明されて、たくさんありがとう!
Zaki Mohammed

など、空の場合はどうなり@Injectable()ますか?
ベンタリアドロス

13

providedInは、ルートインジェクタがサービスのインスタンスを作成する責任があることをAngularに伝えます。この方法で提供されるサービスは、アプリケーション全体で自動的に利用可能になり、どのモジュールにもリストする必要はありません。

サービスクラスは独自のプロバイダーとして機能できます。そのため、@ Injectableデコレーターでサービスクラスを定義するだけで、必要な登録を行うことができます。


4

によるとDocumentation

@Injectable()メタデータにプロバイダーを登録すると、Angularは、コンパイルされたアプリが使用されていない場合は、サービスを削除してアプリを最適化することもできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.