我正在尝试构建一个 DI 容器,但偶然发现了以下问题:我有一个方法可以检索给定类型的注册实例列表,我想用它来注入IEnumerable<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);
My 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>
,因为它是一个。
你可以考虑使用IEnumerable
and Cast<T>
,但是你没有列表的实例。我不知道拥有一个有多重要。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)