1. ホーム
  2. dependency-injection

[解決済み] DIコンテナを介して作成されたオブジェクトを初期化するパターンはありますか?

2022-05-04 21:15:24

質問

Unityにオブジェクトの生成を管理させようとしていますが、実行時までわからない初期化パラメータを用意したいのです。

今のところ、その方法はインターフェースにInitメソッドを持たせるしか思いつきません。

interface IMyIntf {
  void Initialize(string runTimeParam);
  string RunTimeParam { get; }
}

それから、(Unityで)使うには、こうします。

var IMyIntf = unityContainer.Resolve<IMyIntf>();
IMyIntf.Initialize("somevalue");

このシナリオでは runTimeParam paramはユーザーの入力に基づき、実行時に決定されます。この場合、単純に runTimeParam しかし実際には、パラメータはファイル名のようなもので、initializeメソッドはそのファイルに対して何らかの処理を行います。

これは、多くの問題を引き起こします。 Initialize メソッドはインターフェイス上で利用可能であり、複数回呼び出すことができます。実装でフラグを立て、何度も Initialize は、非常に不格好です。

インターフェースを解決する時点で、私は IMyIntf . しかし、私が欲しいのは、このインターフェースが特定の1回限りの初期化パラメータを必要とするという知識です。この情報をインターフェイスにアノテート(属性?)して、オブジェクトが生成されるときにそれらをフレームワークに渡す方法はないでしょうか?

編集:インターフェイスをもう少し詳しく説明します。

解決方法は?

特定の依存関係を構築するためにランタイム値が必要なあらゆる場所。 抽象ファクトリー が解決策になります。

の匂いのするインターフェースにInitializeメソッドを持たせる。 抽象化の漏れ .

あなたの場合、私はモデル化された IMyIntf インターフェイスを どのように使用する必要があるのか - その実装をどのように作成するつもりかではなく それは実装の詳細です。

したがって、インターフェースは単純にこうあるべきだ。

public interface IMyIntf
{
    string RunTimeParam { get; }
}

次に、抽象ファクトリーを定義します。

public interface IMyIntfFactory
{
    IMyIntf Create(string runTimeParam);
}

の具体的な実装を作成することができます。 IMyIntfFactory の具体的なインスタンスを作成するものです。 IMyIntf このように

public class MyIntf : IMyIntf
{
    private readonly string runTimeParam;

    public MyIntf(string runTimeParam)
    {
        if(runTimeParam == null)
        {
            throw new ArgumentNullException("runTimeParam");
        }

        this.runTimeParam = runTimeParam;
    }

    public string RunTimeParam
    {
        get { return this.runTimeParam; }
    }
}

これにより、次のようなことが可能になることに注目してください。 クラスの不変量を保護する を使用することで readonly キーワードを使用します。胡散臭いInitializeメソッドは必要ありません。

を使用します。 IMyIntfFactory のようなシンプルな実装が考えられます。

public class MyIntfFactory : IMyIntfFactory
{
    public IMyIntf Create(string runTimeParam)
    {
        return new MyIntf(runTimeParam);
    }
}

を必要とするすべてのコンシューマで IMyIntf インスタンスに依存します。 IMyIntfFactory でリクエストすることで コンストラクタ・インジェクション .

DIコンテナであれば、DIコンテナ内で IMyIntfFactory インスタンスを正しく登録すれば、あなたのために