5

したがって、制御の反転はあいまいな説明であるため、依存性注入が新しい定義になりました。これは非常に強力なソリューションであり、これに遭遇したことのない人にとっては混乱を招く可能性があります。

それで、ヘッドライトの鹿にならないように、私は読み上げました。いくつかの素晴らしい本とオンライン投稿を見つけました。しかし、すべての素晴らしいことと同様に、答えよりも多くの疑問が生じました。

問題は、未知のプロジェクトから変数を吸収して、プロジェクトに導入された後に実装されることです。

ソリューション:

public interface ISiteParameter
{
    Guid CustomerId { get; set; }
    string FirstName { get; set; }
    string LastName { get; set; }
    string Phone { get; set; }
}

私のインジェクター:

public interface IInjectSiteParameter
{
     void InjectSite(ISiteParameter dependant);
}

次に、これを作成しました:

public class SiteContent : IInjectSiteParameter
{
    private ISiteParameter _dependent;

    #region Interface Member:
    public void InjectSite(ISiteParameter dependant)
    {
        _dependant = dependant;
    }
    #endregion
}

次に、共有参照を使用して Fed Variablesとして実装するために、次のように実装するクラスを作成しました。

public class SiteParameters : ISiteParameter
{    
   public Guid Customer Id { get; set; }
   public string FirstName { get; set; }
   public string LastName  { get; set; }
   public string Phone { get; set; }
}

これでSiteParameters Class、他のプロジェクトによって参照されます。これにより、いつでもどこでもこれらのプロパティを実際に呼び出すことができます。

ISiteParameter i = new ISiteParameter();
MessageBox.Show(i.Guid + i.FirstName + i.LastName + i.Phone);

それが実装でしたが、私の質問はこれです...いつ使用しますか?

  • コンストラクター インジェクション
  • セッター注入
  • インターフェース注入

どちらか一方をいつ使用しますか?そして、私が言及したタスクについては、他のプロジェクトに加えられた変更を調整するために、このような難しいタスクを実装する必要がありますか?

思考過程で曲線から外れましたか?

4

2 に答える 2

3

Mark Seemann による.NET の Dependency Injectionの第 4 章から引用

コンストラクター インジェクションは、DI の既定の選択肢です。クラスが 1 つ以上の依存関係を必要とする最も一般的なシナリオに対処します。依存するクラスが依存関係なしでは絶対に機能できない場合、その保証は価値があります。

プロパティ注入は、開発中のクラスに適切なローカル デフォルトがあり、呼び出し元がクラスの依存関係のさまざまな実装を提供できるようにしたい場合にのみ使用する必要があります。プロパティ インジェクションは、ASP.NET ページのように、フレームワークで既定のコンストラクターが必要な場合にも使用できます。

メソッド注入は、メソッド呼び出しごとに依存関係が異なる場合に最適です。これは、依存関係自体が値を表す場合に発生する可能性がありますが、操作が呼び出されているコンテキストに関する情報を呼び出し元がコンシューマーに提供したい場合によく見られます。

于 2013-03-07T00:32:30.933 に答える
1

可能な限り、メソッド呼び出しを介して注入する代わりに、コンストラクターを使用して依存関係を渡します。

例えば:

public interface IWebHost 
{ 
   string DoSomething(string input); 
} 

public class FooManager 
{
   private IWebHost _host; 
   public FooManager(IWebHost host)
   {  
      _host = host; 
   } 

   public void Process()
   { 
      // do something with _host 
   }
} 

これには多くの利点がありますが、私が最も有益だと思う2つは次のとおりです。

  • 私の依存関係は事前に指定されているため、見逃される可能性は低くなります。
  • 依存性注入リポジトリを使用して、自動的に構築を行うことができます。

これを行うことが不可能または非現実的なシナリオがありますが、それらのほとんどは、私のために構築を行う Factory を注入することで回避できます。

もう一つの例:

public interface IConnection : IDisposable 
{
   string DoSomething(string input); 
   // implement IDisposable
}

public interface IConnectionFactory 
{
   IConnection CreateConnection(); 
} 

public class DerpConnection : IConnection 
{
    // implementation
} 

public class DerpConnectionFactory : IConnectionFactory 
{
  // We only return DerpConnections from this factory.  

  IConnection CreateConnection() { return new DerpConnection(); } 
}

public class BarManager 
{ 
   private IConnectionFactory _connectionFactory; 
   public BarManager(IConnectionFactory connectionFactory)
   {   
      _connectionFactory = connectionFactory;
   } 

   public void Manage()
   {
      using(var connection = _connectionFactory.CreateConnection()) 
      { 
        // do something here. 
      } 
   }
}

DI フレームワークは、この例の についてのみ知る必要がIConnectionFactoryあり、Factory 実装は を直接構築しDerpConnectionます。単体テストでは、ファクトリと IConnection の応答を簡単にモックできます。

これが不可能なシナリオは、通常、何らかの分野横断的な懸念を示しているか、クラスが必要以上に複雑である (そしてSRPに違反している)ことを示しています。

于 2013-03-07T00:41:09.130 に答える