25

依存性注入は良いことのようです。一般に、依存関係は、依存関係を必要とするメソッドに注入する必要がありますか、それともクラスのコンストラクターに注入する必要がありますか?

同じ依存関係を注入する2つの方法を示すには、以下のサンプルを参照してください。

//Inject the dependency into the methods that require ImportantClass
Class Something {

    public Something()
    {
         //empty
    }

    public void A() 
    {
         //do something without x
    }

    public void B(ImportantClass x)
    {
         //do something with x
    }

    public void C(ImportantClass x)
    {
         //do something with x
    }
}

//Inject the dependency into the constructor once
Class Something {
    private ImportantClass _x
    public Something(ImportantClass x)
    {
         this._x = x;
    }

    public void A() 
    {
         //do something without x
    }

    public void B()
    {
         //do something with this._x
    }

    public void C()
    {
         //do something with this._x
    }

}
4

5 に答える 5

17

コンストラクターインジェクションの主な利点は、フィールドをfinalとしてマークできることです。例えば:

class Foo {
    private final Bar _bar;

    Foo(Bar bar) {
        _bar=bar;
    }
}

次のページには、賛否両論のすばらしいリストがあります。Guiceのベストプラクティス

メソッド注入

  • +フィールドインジェクションではありません
  • +いくつかの奇妙なエッジケースで機能するものだけ

コンストラクター注入

  • +フィールドは最終的なものになる可能性があります!
  • +注入をスキップできなかった可能性があります
  • +依存関係が一目でわかります
  • +それが建設のアイデアのすべてです
  • -オプションの注射はありません
  • -DIライブラリ自体がインスタンス化できない場合は役に立ちません
  • -サブクラスは、スーパークラスに必要なインジェクションについて「知る」必要があります
  • -パラメータの1つだけを「気にする」テストにはあまり便利ではありません
于 2008-10-17T18:59:05.700 に答える
3

各メソッドに依存関係を注入しないことで、各呼び出し元に依存関係を認識または取得させることができます。

また、ツールの観点から、(少なくとも .NET では) 利用可能なフレームワークが多数あり、コンストラクター インジェクションを有効にしたり、はるかに簡単に実行したりできます。これは決定を左右するものではありませんが、より魅力的なものにします。

幸運を。

于 2008-10-17T19:02:02.543 に答える
3

メソッド中に注入する場合、動作の抽象化と具体的な依存関係を区別していません。これは大したことではありません:)。抽象化に依存したいので、クラスの依存関係と結合されません。. .

コンストラクターは、具体的なクラスがサポートするインターフェイスには存在しないため、その依存関係に結合していません。しかし、メソッド呼び出しにはその問題があります。

このティオピックに関する良い記事は次のとおりです。

http://chrisdonnan.com/blog/2007/05/20/conquest-through-extreme-composition-glue-part-2/

于 2008-10-26T23:14:31.353 に答える
2

もう 1 つの方法は、依存関係のセッターを使用することです。時々これはコンストラクター注入と組み合わされます。これは、インスタンスを再作成せずに後で使用する実装を変更したい場合に役立ちます。

public interface IFoo
{
   void Do();
}

public class DefaultFoo : IFoo
{
   public void Do()
   {
   }
}

public class UsesFoo
{
   private IFoo foo;
   public IFoo Foo
   {
       set { this.foo = value; }
   }

   public UsesFoo()
   {
      this.Foo = new DefaultFoo();
   }

   public UsesFoo( IFoo foo )
   {
      this.Foo = foo;
   }

   public void DoFoo()
   {
      this.Foo.Do();
   }
}
于 2008-10-17T19:25:35.523 に答える
0

Crazy Bob Leeは、可能な限りコンストラクター インジェクションを使用すると述べています。インスタンス化を制御できない場合 (サーブレットの場合など) にのみ、メソッド インジェクションを使用してください。

于 2008-10-17T19:02:05.803 に答える