5


2

Autofac-パラメータを使用してコンポーネントを動的に解決する

コンストラクターの引数としてインターフェイスを取るクラスがあります。 このインターフェイスには2つの実装があり、変数に基づいて実行時に使用する実装を決定します。

問題は、上記のクラスがAutofacによって解決されるオブジェクト階層の奥深くにあるため、引数を渡すことができないことです。

以下のような何かが私が達成しようとしているものです。

public interface IInterface1 {}
public interface IInterface2 {}

public class Class1 : IInterface2
{
    public Class1(IInterface1 interface1)
    {
    }
}

public class Class2
{
    public Class2(IInterface2 interface2)
    {
    }
}

public class Class3
{
    public void GetClass2Instance(string interface1ImplementationToChoose)
    {
        // want to change which implementation of IInterface1 is resolved based on the interface1ImplementationToChoose variable
        var class2 = container.Resolve();
    }
}

何か案は?

更新:

明確にするために、これは既存のオブジェクト階層であり、正常に動作する既存のアプリケーションで使用されます。 また、オブジェクトモデルは、この例に示されているものよりもはるかに大きくなります。 その結果、オブジェクトグラフ内の各コンストラクターにファクトリーを渡して、そのグラフの深いクラスで使用されるようにする必要はありません。

Class2が何も知らずにIInterface1の異なる実装をClass1に渡す方法はありますか?

ありがとう

1 Answer


6


はい、タイプの選択方法を隠すファクトリを挿入します。

public class Class3
{
   private Func _class2Factory;
   public Class3(Func class2Factory)
   {
        _class2Factory = class2Factory;
   }

   public void GetClass2Instance(string interface1ImplementationToChoose)
   {
       var class2 = _class2Factory(interface1ImplementationToChoose);
   }
}

そして、コンテナのセットアップ、これらの行に沿って何か:

builder.RegisterType().Named("imp1").As();
builder.RegisterType().Named("imp2").As();
builder.Register>(c =>
    {
        var context = c.Resolve();
        return imp => new Class2(context.Resolve(imp));
    });
builder.RegisterType();

次のように `Class3`を使用できます。

public class Class4
{
     public Class4(Class3 class3)
     {
         var class2with1 = class3.GetClass2Instance("imp1");
         var class2with2 = class3.GetClass2Instance("imp2");
     }
}

*注意:*私は、 Class2`に同じインターフェース IInterface1`のさまざまな実装をインジェクトすることを意味すると想定しました。 異なるインターフェイスを実装する2つのクラスを示しているため、サンプルは少しわかりにくいです。