2012-05-02 8 views
2

私はAutofacを学び、サービス間の依存関係を解消する方法を理解しようとしています。Autofac:他のクラスの特定のインスタンスに依存するクラスを登録してください

class ClassA {} 
class ClassB {} 
class ClassC {} 

class Classes 
{ 
    public Classes(ClassA classA, ClassB classB, ClassC classC) 
    { 
     ... 
    } 
} 

と私はそれが以下の行動を模倣するようにクラスを登録したいこと:

は、私は以下のクラスを持っていると言います。要するに

var classA1 = new ClassA("A1"); 
var classB1 = new ClassB("B1"); 
var classC1 = new ClassC("C1"); 
var classes1 = new Classes(classA1, classB1, classC1); 

var classA2 = new ClassA("A2"); 
var classB2 = new ClassB("B2"); 
var classC2 = new ClassC("C2"); 
var classes2 = new Classes(classA2, classB2, classC2); 

ClassesClassAClassBClassCの特定のインスタンスに依存しています。それ、どうやったら出来るの?

答えて

4

クラスクラスの複数の一意のインスタンスを作成できるようにしたい場合は、parameter passingのAutofac機能を使用して登録を行います。私のコードは、最初の3つのレジスタ呼び出しがAutofacを言っている

var builder = new ContainerBuilder(); 
builder.Register((c,p) => new ClassA(p.Named<string>("a"))); 
builder.Register((c,p) => new ClassB(p.Named<string>("b"))); 
builder.Register((c,p) => new ClassC(p.Named<string>("c"))); 
builder.Register((c,p) => new Classes(
    c.Resolve<ClassA>(new NamedParameter("a", p.Named<string>("ClassA"))), 
    c.Resolve<ClassB>(new NamedParameter("b", p.Named<string>("ClassB"))), 
    c.Resolve<ClassC>(new NamedParameter("c", p.Named<string>("ClassC"))))); 

var container = builder.Build(); 
var classes = container.Resolve<Classes>(
    new NamedParameter("ClassA", "AAAA"), 
    new NamedParameter("ClassB", "BBBB"), 
    new NamedParameter("ClassC", "CCCCC")); 

のようになります。そのことは、それが持つNamedParameterのインスタンスから値を抽出する使用する必要がありますにClassA(またはBまたはC)のインスタンスを構築したいとき"a"(または "b"または "c")の名前を返し、その値をClassAのコンストラクタに渡します。 NamedParameterオブジェクトは、Resolve<ClassA>(new NamedParameter("a", "AAAA"))のようにResolve呼び出しの一部としてパスになります。

最後のレジスタ呼び出しは、ClassA、ClassB、およびClassCのインスタンスを解決し、それらのインスタンスをクラスのコンストラクタに渡す必要があることをAutofacに伝えています。これらの依存関係を解決するために、Autofacは渡されたNamedParameterのインスタンスから値を抽出し、新しいNamedParameterインスタンスのResolveにそれらを渡す必要があります。

2つの注意点があります。

  1. 新しいクラスを作成する代わりに、クラスの登録呼び出しでNamedParameterインスタンスを再利用することができます。匿名関数のpパラメータはIEnumerableなので、可能かもしれません。
  2. このコードは、最新バージョンのAutofac(2.6.1)を使用してテストされました。
+0

その後、私は、まさにこのようにそれを解決するまで終わりませんでしたが、あなたのポインタのおかげで、私は '(「にClassA」) .Named RegisterType を()を使用して、それを動作するように管理し、'、と '登録(( c、p)=>新しいクラス(c.ResolveNamed ( "ClassA"))) '。ありがとう! –

2

最も簡単な方法は、ライフタイムスコープを使用することです。このようなあなたのクラス登録:今、あなただけのコンテナから同じようscopeからインスタンスを解決できますが、各スコープは、別々のインスタンスを持っている

var scope = container.BeginLifetimeScope(); 

builder.RegisterType<ClassA>().InstancePerLifetimeScope(); 
builder.RegisterType<ClassB>().InstancePerLifetimeScope(); 
builder.RegisterType<ClassC>().InstancePerLifetimeScope(); 

よりもこのような生涯スコープを作成ClassA,ClassBおよびClassC

関連する問題