2012-08-15 3 views
6

DI 컨테이너를 만들려고하는데 다음과 같은 문제가 발생했습니다 : 주어진 타입의 등록 된 인스턴스 목록을 가져 오는 메소드가 있습니다. 해당 개체에 IEnumerable<T> 속성을 주입하는 데 사용하십시오. 나는 그 순간에 어떤 유형의 정보가 없습니다 주로 때문에,캐스팅리스트 <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>에 그 목록을 변환하려고 오전 : 내가 달성하기 위해 노력하고 무엇의 예는 다음과 같은 것 주입 시간. 여기에 일을하는 방법의 간결 형식은 다음과 같습니다

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.는 슬프게도, 나는 여기에서 진행하는 방법을 모르겠어요. 아마도 나는이 모든 것을 잘못하고있다. 제네릭을 사용하거나 여러 속성을 수동으로 주입하는 방법을 생각했지만 실제로 그렇게 할 필요가 없습니다.

도움이나 아이디어를 미리 보내 주셔서 감사합니다. 그것은 하나이기 때문에,

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

이 목록은 IList<T>에 주조 할 수 있습니다

답변

6

은이 같은 일반적인 목록을 만들 수 있습니다.

IEnumerableCast<T>을 사용할 수는 있지만 목록의 인스턴스는 없습니다. 나는 그것이 얼마나 중요한지 알지 못한다.

+0

새로운 소식입니다. 당신이 일반적인 유형을 완전하게 만들 수 있다는 것을 몰랐습니다. 나는 지금 그것을 시도 할 것이다. –

+0

감사합니다. 완벽하게 작동했습니다! –