使用反射动态创建存储库实例

本文关键字:存储 实例 创建 动态 反射 | 更新日期: 2023-09-27 18:34:03

对于给定的存储库接口IRepository<T> where T: Base和一堆继承Base的类(例如,Text),您如何创建实现IRepository的提供程序的实例,例如JsonRepository<T> Text作为T (JsonRepository<Text>)并在其上运行方法?

我想将反射与forforeach一起使用,为所有继承Base的类创建存储库的实例,并对其执行一些数据管理功能。

我想避免的是 - 如果你有 100 个类继承Base类,你显然不会在代码中手动创建实例然后运行它?

使用反射动态创建存储库实例

您可以使用Activator.CreateInstance

请参阅此处的示例:

修改为您的示例:

var d1 = typeof(JsonRepository<>);
Type[] typeArgs = { typeof(Text) };
var makeme = d1.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(makeme);

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

您目前使用泛型约束,但为什么不使用"new"约束,该约束表示泛型类型具有公共无参数 ctor,即

IRepository<T> where T: Base, new

这意味着您可以致电:

abstract class ctor()
{
    IRepository rep = new T();
}

现在如何应用它可能是通过一个基本的抽象类,或者你可以简单地通过一个 propfull 返回 rep 实例......这取决于你。

我不得不承认你的问题有点模糊,所以如果这不是你要说的,请原谅。