GitBookプロバイダーの種類と選び方この章の内容を理解するには以下の前提知識が必要です。​公式チュートリアルのサービスの章を理解していることAngularの依存性の注入の概要を理解していることAngularのDIプロバイダーの概要を理解していることAngularのDIには4種類のプロバイダーがあります。それぞれに目的があり、適した用途があります。チュートリアルでは述べられていない、プロバイダーの選び方の指針を理解しましょう。トークンとする値プロバイダーを使いましょう。提供したいものは関数の戻り値ですか?実行時に値が確定する動的なオブジェクトを提供したい場合には2つの選択肢があります。使って、Angularに値の作り方を教える方法です。次の例では2つのプロバイダーは実質的に同じ結果を生みます。ファクトリー関数をAngularに渡します});もしファクトリー関数が依存する引数が完全にAngularから切り離されている場合は、結果だけをアプリケーションに関連付ける値プロバイダーのほうがシンプルに済むでしょう。関数がAngularに依存しないユニットテストを記述できる状態だということです。逆に、ファクトリー関数がひとつでもAngularやアプリケーションが提供する他のサービスへの依存性をもつ場合、つまりファクトリー関数の中でDIをおこないたいときにはファクトリープロバイダー以外の選択肢はありません。APIに依存した関数をファクトリープロバイダーに渡しています。getSomeValue,});ファクトリープロバイダーはどんな値でも自由に解決して提供できる強力なプロバイダーですが、その分ソースコードの可読性やメンテナンス性を損なう危険性もあります。ファクトリープロバイダーでないと解決できないものはほとんどありません。基本的には、依存性を持てない値プロバイダーと、すべての依存性をDIで解決できるクラスプロバイダーの2つだけを使うように心がけることを推奨します。提供したいものはクラスインスタンスですか?クラスインスタンスを提供したい場合には3つの選択肢があります。第一にクラスプロバイダーを利用してインスタンス化をAngularに委譲する方法、第二にファクトリープロバイダーを使ってあなたがインスタンス化をおこなう方法、第三にあなたがインスタンス化したインスタンスオブジェクトを値プロバイダーで提供する方法です。原則として常にクラスプロバイダーを使うべきです。クラスプロバイダーで提供可能な状態にクラスを保つことが結果的にアプリケーションのテスタビリティやモジュール性を維持することにつながるからです。サードパーティSDKの抽象化の例のように、プラットフォームに依存するプロバイダーについては例外的な実装が好ましい場面もあります。デコレーターを付与するだけで、ファクトリー関数について考慮する必要はありません。{}}DIで解決できない引数があるときには?クラスの中にはDIで解決できないコンストラクタ引数を受け取りたいものもあります。ようなオブジェクトや、環境変数などから導かれる設定値が考えられます。そのようなクラスは、理論的には次のようにファクトリープロバイダーを使ってインスタンス化することができるでしょう。{}}確かにこのプロバイダーは正しく動作しますが非効率的なコードです。クラスのコンストラクタ引数が増えるたびに、ファクトリー関数にも手を加える必要があります。DIによる解決が必要な引数かどうかは開発者の頭の中にしか答えがありません。テストのためにモック化するのが困難です。何よりも避けたいのは、ソースコードの中でクラスプロバイダーで提供されるクラスとそうでないクラスが混在することで一貫性を失うことです。引数もDIで解決できるように別のプロバイダーを作るべきです。他のサービスと同じようにクラスプロバイダーで提供します。配列に同じトークンのプロバイダーを宣言することで簡単に上書きできます。上記の例でUserAgent文字列を変えたテストをする場合は次のように記述できます。});});ここまでの内容をまとめると、次の図のようになります。新しくプロバイダーを宣言するときに参考にしてください。提供したいものはクラスインスタンスですか?シンプルなクラスプロバイダーDIで解決できない引数があるときには?。