2009-07-27 49 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

Autofac支持開放式泛型。您可以使用下面的代碼,如果泛型類型是在編譯時已知:

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

更正。您不能從Container調用MakeGenericType。我解決了使用'TYPE'作爲Resolve調用參數來實例化泛型的問題。建造者被註冊。

 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); 
     } 

感謝您對本文的幫助,希望本更新能夠幫助您。