私は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>
にそのリストを変換しようとしています噴射時に。ここで仕事をしている方法の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.
は悲しいことに、私はここから出発するのか分かりません。おそらく私はこれをすべて間違ってやっています。私はジェネリックを使うことや、複数のプロパティを手で注入することを考えていましたが、実際にそれをする必要はありません。
ご協力いただきありがとうございます。それは1つであるため、
public virtual IList Retrieve(Type type)
{
// ...
listType = typeof(List<>).MakeGenericType(new Type[] { type });
IList list = (IList)Activator.CreateInstance(listType);
// ...
return list
}
このリストはIList<T>
にキャストすることができます。
これは新しいものです。ジェネリックタイプを完全に作成できるかどうかは分かりませんでした。私は今それを試してみます。 –
ありがとう、それは完璧に働いた! –