2012-08-15 46 views
6

我試圖建立一個DI容器,我偶然發現了以下問題:我有一個方法檢索給定類型的註冊實例列表,我想使用它在給定對象中注入IEnumerable<T>屬性。什麼,我想實現的一個例子是以下幾點:Casting List <object>到列表<T>在運行時

class A { public IList<IExample> Objects { get; set; } } 
class B: IExample {} 
class C: IExample {} 
Container.Register<IExample>(new B()); 
Container.Register<IExample>(new C()); 
var obj = new A(); 
Container.Inject(A); 
Debug.Assert(A.Objects != null && A.Objects.Count == 2); 

Retrieve方法返回一個IList<object>,主要是因爲我在那一刻沒有類型的信息,所以我試圖到該列表轉換爲List<T>在注射時。這裏是做工作的方法succint形式:

public virtual IList<object> Retrieve(Type type) 
{ 
    var instances = Registry[type]; 
    foreach(var instance in instances) 
     Inject(type, instance); // omitted 
    return instances; 
} 

public virtual void Inject<T>(T instance) 
{ 
    var properties = typeof (T).GetProperties(); 
    foreach (var propertyInfo in properties) 
    { 
     var propertyType = propertyInfo.PropertyType; 
     if (!IsIEnumerable(propertyType)) continue; 
     var genericType = propertyType.GetGenericArguments()[0]; 
     propertyInfo.SetValue(instance, 
      GetListType(genericType, Retrieve(genericType)), null); 
    } 
} 

protected virtual object GetListType(Type type, IEnumerable<object> items) 
{ 
    return items.Select(item => Convert.ChangeType(item, type)).ToList(); 
} 

的代碼返回錯誤:System.InvalidCastException : Object must implement IConvertible.可悲的是,我不知道如何從這裏着手。也許我做這一切都是錯誤的。我想過使用泛型或手動注入多個屬性,但我真的不想那樣做。

在此先感謝您的幫助或意見。

回答

6

您可以創建一個通用的清單如下:

public virtual IList Retrieve(Type type) 
{ 
    // ... 
    listType = typeof(List<>).MakeGenericType(new Type[] { type }); 
    IList list = (IList)Activator.CreateInstance(listType); 
    // ... 
    return list 
} 

這個列表可以鑄造到IList<T>,因爲它是一個。

你可以考慮使用IEnumerableCast<T>,但是你沒有列表的實例。我不知道它有多重要。

+0

這是新鮮事。我不知道你可以直接創建一個泛型類型。我現在就試試。 – 2012-08-15 08:21:40

+0

謝謝,它工作完美! – 2012-08-15 08:22:51

相關問題