Estoy intentando construir un contenedor DI y he tropezado con el siguiente problema: Tengo un método que recupera una lista de instancias registradas para un tipo determinado y quiero utilízalo para inyectar propiedades IEnumerable<T>
en un objeto dado. Un ejemplo de lo que estoy tratando de lograr sería la siguiente:Casting List <object> en la lista <T> en tiempo de ejecución
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);
Mi método Retrieve
devuelve un IList<object>
, sobre todo porque no tengo información de tipo en ese momento, así que estoy tratando de convertir esa lista en un List<T>
en el momento de la inyección Aquí es una forma sucinta de los métodos que realizan el trabajo:
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();
}
El código devuelve el error: System.InvalidCastException : Object must implement IConvertible.
Lamentablemente, no sé cómo proceder desde aquí. Quizás estoy haciendo todo mal. He pensado en usar genéricos o inyectar múltiples propiedades a mano, pero realmente me gustaría no tener que hacer eso.
Gracias de antemano por cualquier ayuda o idea.
Eso es algo nuevo. No sabía que podrías crear un tipo genérico directamente. Lo intentaré ahora mismo. –
¡Gracias, funcionó perfectamente! –