2011-01-19 13 views
15

私はDIを使った2番目の実生活アプリケーションを書いています。全体的に私はそれがより良いデザインにしたと思う。しかし、いくつかのコードの匂いがある、私は解決する方法を知らない。DI:注射する量は?

私はコンストラクタインジェクションを使いたいと思っています。コンストラクタに注入するオブジェクトが5個以上必要になることがよくあります。それは多すぎるようですが、おそらくSRPを正しく取得できないという設計上の問題です。しかし私はDIの私の使用も非難されると思います。

私は "ベストプラクティス"または "経験則"を探していますが、一般的には.Netフレームワークではないすべてのものを注入しているようですが、それはそれを徹底していますか?

私が注入するオブジェクトの2つの例がここにありますが、不明な点があります。

アプリケーション構成や小さなutilクラスのような真のシングルトンであるオブジェクトは、注入しますか? 彼らは非常に頻繁に注射されるようですが、注射する唯一の理由は検査の価値を変えることができるようですが、Ayendeは別の方法で問題を解決したようです:http://ayende.com/Blog/archive/2008/07/07/Dealing-with-time-in-tests.aspx

ほとんどのオブジェクトで使用されるロギングなどの一般的なオブジェクトは、注入する必要がありますか?

答えて

3

親指の私の個人的なルールはこれです:

  • あなたはあなたがテストの目的のためにそれを代用することができるようにしたい場合は
  • がそれを注入不変になりたい場合は、それを注入

サービスのようなものは、それらの基準の両方を満たすことができます。消費者は決してそれを変更すべきではなく、テスト時に代わることができるようにしたいと考えています。変更不能な項目では、消費オブジェクト上にプロパティを持つ可能性がありますが、そのプロパティにはセッターがなく、ゲッターしかありません。値を変更する場合は、オブジェクトの新しいインスタンスを作成する必要があります。

ロガーを注入する必要がありますか?

理由はありません。ロガーは、通常、静的クラスを介して公開され、構成エントリから新しく作成されるため、テスト目的でも、注入する必要はありません。

アプリケーション設定のような真のシングルトンを注入する必要がありますか?

また、テスト目的で簡単に変更できるグローバルにアクセス可能なオブジェクトであるため、注入する必要はありません。私がこれを注入する唯一の時間は、消費者が「切断された」場合です。リフレクションを介して生成されるか、またはウェブサービスまたはリモートオブジェクトとして呼び出される。

DIは素晴らしいパターンですが、あまりにも多くの良いことは依然として不健全である可能性があります。あなたがコードの匂いが増えていると感じたら、注入している各項目を調べ、質問をしてください。i NEEDこのパラメータを注入するには?

+2

を、あなたのクラスは、全体に依存します他の場所で使うのは難しいでしょう。オブジェクトが気にする設定の特定の部分を注入する方がよいでしょう。 –

12

私はしばしば、単体テストを正しく書いているようなものを注入します。これを行うと、BCLクラス(DateTimeなど)を抽象化してしまうことがあります。今、ファイルなど)、時には自分のもの。注入するのが良いサービス(ICustomerService、ICustomerUnitOfWorkFactory、またはICustomerRepositoryなど)です。エンティティ、DTO、メッセージなどを注入しないでください。

しかし、モジュールを後で置き換えることができる(たとえば、検証、UI、またはO/RMのためのスイッチ実装)、チーム内またはチーム間の並列開発を可能にする、メンテナンスを減らすことができます。

私はコンストラクタ・インジェクション を使用することを好むと、多くの場合、私はコンストラクタで を注入される 約5以上のオブジェクトを必要とすることを観察しました。

あなた自身がすでに気づいたように、多くの依存関係はSRPを遵守しないと発生する可能性があります。しかし、あなたができることは、ロジックとの共通の依存関係を集約サービスにグループ化し、それを消費者に注入することです。 Aggregate ServicesについてのMark Seemannの記事も参照してください。 アプリケーション構成またはそれらの 小さなutilのクラスのような本当のシングルトンです

オブジェクトは、あなたが それらを注入しますか?

私は個人的にアヘンデが提案する方法のファンではありません。これは具体的な種類のservice locator構成であるAmbient Contextです。これを行うと、依存関係が隠されます。なぜなら、クラスは、静的クラスを注入することなく呼び出すことができるからです。明示的に注入すると、単位テスト時間が必要であることがはっきりと分かります。それに加えて、テストを並行して実行する傾向のあるMSTestなどのフレームワークのテストを作成するのは難しくなります。何の対策もなしに、あなたのテストは非常に信頼できません。例:DateTime.Nowの場合のより良い解決策は、hereのように、IClockインターフェイスを持つことです。あなたが見ることができるように、その答えはAyendeのアプローチよりもはるかに高い、それは同じSOの質問に示されています。 は、ほぼすべてのオブジェクトで使用されていることをロギングなど

一般的なオブジェクトは、 は彼らを注入すべきか?

私はそれらを依存関係を明確にするためにコードに挿入します。しかし、私のコードではまだロガーを注入する必要はほとんどありません。あなたがログに記録するすべての行について懸命に考えると、それは実際には失敗ではありません(または、他の場所に配置されるべきクロスカッティングの懸念事項)。私は通常、何かが起こったときに例外を投げ、私が期待していなかった。それは私がバグを早く見つけることを可能にする。または、言い換えると、フィルタリングはしませんが、速く失敗します。そして、あなた自身に尋ねてください: "Do I log too much?"

私はこれが役立つことを望みます。

3

良い出発点は、Volatile Dependenciesを注射することです。

さらに疎結合のために安定した依存関係を注入することもできますが、優先順位を付ける必要がある場合は、揮発性の依存関係を開始するのが最適です。過注入コンストラクタに関する

、それは本当にSRPを破るだけの症状です:この関連の質問を参照してください。あなたがグローバル(または静的)などのアプリケーションの設定にアクセスした場合How to avoid Dependency Injection constructor madness?