C# 使用反射动态创建存储库实例
对于给定的存储库接口C# 使用反射动态创建存储库实例,c#,reflection,repository-pattern,C#,Reflection,Repository Pattern,对于给定的存储库接口IRepository,其中T:Base和继承Base的一组类(例如,Text),如何创建实现IRepository的提供程序的实例,例如JsonRepository,其中Text作为T(JsonRepository)并在其上运行方法 我想将反射与for或foreach一起使用,为继承Base的所有类创建存储库实例,并对它们执行一些数据管理功能 我想避免的是——如果您有100个类继承Base类,您显然不会在代码中手动创建实例然后运行它?您可以使用 请参见一个示例: 修改为您的
IRepository,其中T:Base
和继承Base
的一组类(例如,Text
),如何创建实现IRepository
的提供程序的实例,例如JsonRepository
,其中Text
作为T
(JsonRepository)并在其上运行方法
我想将反射与for
或foreach
一起使用,为继承Base
的所有类创建存储库实例,并对它们执行一些数据管理功能
我想避免的是——如果您有100个类继承Base
类,您显然不会在代码中手动创建实例然后运行它?您可以使用
请参见一个示例:
修改为您的示例:
var d1 = typeof(JsonRepository<>);
Type[] typeArgs = { typeof(Text) };
var makeme = d1.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(makeme);
var d1=typeof(JsonRepository);
Type[]typeArgs={typeof(Text)};
var makeme=d1.MakeGenericType(typeArgs);
对象o=Activator.CreateInstance(makeme);
您当前使用的是泛型约束,但为什么不使用表示泛型类型具有公共无参数ctor的“新”约束呢
IRepository<T> where T: Base, new
现在,您可以通过一个基本抽象类来应用它,也可以通过propfull返回rep实例……这取决于您自己
我必须承认你的问题有点模糊,如果你不是想问这个,请原谅。在@SwDevMan81的帮助和一些思考下,我成功地解决了这个问题,它实际上非常有效:
var type = typeof(Base);
var types = AppDomain.CurrentDomain.GetAssemblies().ToList()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
var jsonProviderClass = typeof(JsonContentProvider<>);
var xmlProviderClass = typeof(XmlContentProvider<>);
foreach (var t in types) {
Type[] typeArgs = { t };
// get XML provider
var xmlGenericProvider = xmlProviderClass.MakeGenericType(typeArgs);
object xmlProvider = Activator.CreateInstance(xmlGenericProvider);
// get JSON provider
var jsonGenericProvider = jsonProviderClass.MakeGenericType(typeArgs);
object jsonProvider = Activator.CreateInstance(jsonGenericProvider);
// methods to run
MethodInfo xmlMethod = xmlGenericProvider.GetMethod("GetContent", new Type[] { typeof(string) });
MethodInfo jsonMethod = jsonGenericProvider.GetMethod("Update");
// get content from XML provider
var result = xmlMethod.Invoke(xmlProvider, new object[] { string.Empty });
// enumerate XML content items
foreach (var item in ((IEnumerable)result)) {
// update them via JSON provider
object[] parametersArray = new object[] { item };
var update = jsonMethod.Invoke(jsonProvider, parametersArray);
}
}
var type=typeof(基本);
var types=AppDomain.CurrentDomain.GetAssemblys().ToList()
.SelectMany(s=>s.GetTypes())
其中(p=>type.IsAssignableFrom(p));
var jsonProviderClass=typeof(JsonContentProvider);
var xmlProviderClass=typeof(XmlContentProvider);
foreach(类型中的var t){
类型[]typeArgs={t};
//获取XML提供程序
var xmlGenericProvider=xmlProviderClass.MakeGenericType(typeArgs);
对象xmlProvider=Activator.CreateInstance(xmlGenericProvider);
//获取JSON提供程序
var jsonGenericProvider=jsonProviderClass.MakeGenericType(typeArgs);
对象jsonProvider=Activator.CreateInstance(jsonGenericProvider);
//要运行的方法
MethodInfo xmlMethod=xmlGenericProvider.GetMethod(“GetContent”,新类型[]{typeof(string)});
MethodInfo jsonMethod=jsonGenericProvider.GetMethod(“更新”);
//从XML提供程序获取内容
var result=xmlMethod.Invoke(xmlProvider,新对象[]{string.Empty});
//枚举XML内容项
foreach(变量项在((IEnumerable)结果中)){
//通过JSON提供程序更新它们
object[]parametersArray=新对象[]{item};
var update=jsonMethod.Invoke(jsonProvider,parametersArray);
}
}
在我看来,你的想法完全错了。数据管理功能?在我看来,这不像是OLTP me,它确实是存储库唯一有用的地方。如果你在做批量数据管理或ETL,就没那么多。不要让你的抽象将你束缚在看待问题的唯一方式上。我对n你在这里问的是什么。你是说你已经有100个类继承了Base,你想通过反射得到这些类的实例,这样你就不必硬编码100个类名了吗?为什么你认为构造函数是无参数的?因为大多数数据源都有一个连接字符串或文件路径,或者一些指示来源是。这看起来很有希望,但仍然需要手动编码typeof(文本)…我希望有一个foreach来枚举那些继承BaseYes的类型,您需要创建一个循环,并只使用所有要创建的Base
类型的类型。让我看看是否可以找到一个示例。这个问题可能会有所帮助。然后只需循环这些类型并使用类型,而不是typeof(Text)
这行不通,你只能创建Base
类的实例。但是Base可以是一个接口/抽象类它当然可以,但它不是一个i假设
推断,就像你的例子中一样在你的例子中,T
派生自Base
,你可以创建一个新的
实例(如果它有一个无参数的构造函数)它没有说明T
实现IRepository
嗯,是的,我明白你的意思了……好吧,我的答案不会切中要害。
var type = typeof(Base);
var types = AppDomain.CurrentDomain.GetAssemblies().ToList()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
var jsonProviderClass = typeof(JsonContentProvider<>);
var xmlProviderClass = typeof(XmlContentProvider<>);
foreach (var t in types) {
Type[] typeArgs = { t };
// get XML provider
var xmlGenericProvider = xmlProviderClass.MakeGenericType(typeArgs);
object xmlProvider = Activator.CreateInstance(xmlGenericProvider);
// get JSON provider
var jsonGenericProvider = jsonProviderClass.MakeGenericType(typeArgs);
object jsonProvider = Activator.CreateInstance(jsonGenericProvider);
// methods to run
MethodInfo xmlMethod = xmlGenericProvider.GetMethod("GetContent", new Type[] { typeof(string) });
MethodInfo jsonMethod = jsonGenericProvider.GetMethod("Update");
// get content from XML provider
var result = xmlMethod.Invoke(xmlProvider, new object[] { string.Empty });
// enumerate XML content items
foreach (var item in ((IEnumerable)result)) {
// update them via JSON provider
object[] parametersArray = new object[] { item };
var update = jsonMethod.Invoke(jsonProvider, parametersArray);
}
}