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);
        }
    }