web-dev-qa-db-ja.com

コンストラクターの注入、単一責任、およびリストの初期化

クラスを考えると:

_public class Foo : IFoo
{
  private IBarRepository repository

  public Foo(IBarRepository repository)
  {
     this.repository = repository
  }

  public IList<IBar> Bars { get; private set; }
}
_

私の長年の本能は、コンストラクターでIBarのリストを初期化することです:this.Bars = new List<IBar>();しかし、コンストラクターインジェクションを使用すると、コンストラクターの単一責任はそれのためですクラスの依存関係を設定します。

これを処理するための最良の方法は何ですか?

コレクションを使用する前に、任意のメソッドで呼び出すコレクション初期化子が必要ですか?

_private void InitialiseCollection()
{
  if (this.Bars == null)
  {
     this.Bars = new List<IBar>();
  }
}

public void Add(IBar bar)
{
    this.InitialiseCollection();
    this.Bars.Add(bar)
}
_
5
NikolaiDante

さて、あなたの質問に対する簡単な答えは

public readonly IList<IBar> Bars = new List<IBar>();

しかし、私はあなたがあなたの前提を疑うべきだと思います。

ただし、コンストラクタインジェクションを使用する場合、コンストラクタの単一責任は、クラスの依存関係を設定することです。

どこで読んだの?それは完全に間違っています。

コンストラクタインジェクションを使用しているかどうかは関係ありません。コンストラクターの責任は、完全に初期化されたオブジェクトを、そのオブジェクトを操作するために必要なすべての依存関係を使用して構築することです。これらの依存関係は、このオブジェクトをそのタイプの別のオブジェクトから区別する他のサービス、状態、または値である可能性があります。

12
pdr

単一責任の原則は、コンストラクターだけでなく、クラス全体に適用されます。また、最後のメソッドを使用してBars変数を初期化する衝動に抵抗します。インジェクションを使用している場合は、Fooの完全で機能するインスタンスを提供するか、渡すオブジェクトを解決できない場合はまったく提供しない必要があります。コンストラクター。

3
Otávio Décio