2009-07-27 13 views
28

次のコードで、Autofacで正しいSomeInstanceを解決する方法を教えてください。Autofacで一般的なインターフェイスを解決する

public class BaseClass {} 

public class SubClass1 : BaseClass {} 

public class SubClass2 : BaseClass {} 

public interface IGenericInterface<T> where T : BaseClass {} 

public class SomeInstance1<T> : IGenericInterface<T> where T : SubClass1 

public class SomeInstance2<T> : IGenericInterface<T> where T : SubClass2 

サブクラスのジェネリックのタイプに基づいて、SomeInstance1または2を選択します。

たとえば、私はサブクラスのコレクション(SubClass1,2 ...)を持っており、それらを反復している間、私は正しいSomeInstanceクラスを選択したいと思います。

答えて

59

オープンファブリックをサポートしています。ジェネリック型はコンパイル時に知られている場合は、次のコードを使用することができます。

var builder = new ContainerBuilder(); 

builder.RegisterGeneric(typeof(SomeInstance1<>)) 
    .As(typeof(IGenericInterface<>));    

var container = builder.Build(); 

var instance1 = container.Resolve<IGenericInterface<SubClass1>>(); 

Assert.IsInstanceOfType(typeof(SomeInstance1<SubClass1>), instance1); 

を型パラメータは(あなたがタイプのコレクションを反復処理したい場合はおそらくあなたのケースで)実行時まで知られていない場合は、あなたが構築することができますMakeGenericTypeを使用しているあなたのタイプ:

 var typeInRuntime = typeof (SubClass1); 
     var instance1 = container.Resolve(typeof(IGenericInterface<>).MakeGenericType(typeInRuntime)); 
1

修正。コンテナからMakeGenericTypeを呼び出すことはできません。 Resolveコールのパラメータとして 'TYPE'を使用してGenericsをインスタンス化する問題を解決しました。ビルダーが登録されています。

 builder.RegisterGeneric(typeof (FakeRepository<>)).As(typeof (IRepository<>)).OnActivating(e => 
     { 
      var typeToLookup = e.Parameters.FirstOrDefault() as TypedParameter; 
      if (typeToLookup != null) 
      { 
       var respositoryType = typeof (FakeRepository<>); 
       Type[] typeArgs = {typeToLookup.Value.GetType()}; 
       var genericType = respositoryType.MakeGenericType(typeArgs); 
       var genericRepository = Activator.CreateInstance(genericType); 
       e.ReplaceInstance(genericRepository); 
      } 
     }); 

次に、解像度はTypedParameterをResolveに渡します。この場合、私はそのタイプのアイテムのすべてのリポジトリを作成したいという解決済みのアイテム(IItem)のリストを持っています。

 var items = container.Resolve<IEnumerable<IItem<string>>>(); 
     foreach (var item in items) 
     { 
      var repository = container.Resolve(typeof (IRepository<DataItemBase>), new TypedParameter(item.GetType(), item)); 
      Assert.IsNotNull(repository); 
     } 

あなたの投稿をいただきありがとうございました。私はこのアップデートが役立つことを願っています。

関連する問題