繁体   English   中英

访问IEnumerable的类型T属性 <T> 从通过反射调用的方法返回

[英]Access to type T properties of IEnumerable<T> returned from a method called via reflection

我有一个.dll和一个控制台应用程序使用所述.dll但不直接引用,它通过反射加载它。 控制台应用程序在.dll中调用类的方法。
方法签名是IEnumerable<Customer> GetAll() ;

在.dll我这样做了:

class CustomerRepository : ICustomerRepository
{
    public IEnumerable<Customer> GetAll()
    {
        using (var db = new DB02Context())
        {
            List<Customer> list = new List<Customer>();

            // some queries to fill the list

            return list;
        }
    }
}

在控制台应用程序中我做到了这一点:

Assembly assembly = Assembly.LoadFrom(pathToMyDLL);
Type t = assembly.GetType("MyDLL.Models.CustomerRepository");

var methodInfo = t.GetMethod("GetAll");

if(methodInfo == null)
    throw new Exception("The method doesn't exists");

var customerRepository = Activator.CreateInstance(t);

// Invoke the GetAll() method
var customerList = methodInfo.Invoke(customerRepository, null);

现在问题是,因为GetAll返回IEnumerable<Customer>并且我的控制台应用程序没有“知道”任何关于MyDLL.dll的信息(我不直接引用它,所以它不知道Customer类型)。

如何访问Customer列表以访问Customer'a属性而无需明确地引用.dll?

你有三个选择

  1. 移动Client或将Client实现的接口移动到反射的DLL和控制台应用程序都可以引用的第3个dll。
  2. 使用dynamic关键字作为对象的类型( dynamic customerList = methodInfo.Invoke(... ),这是它发明的确切情况。
  3. 将返回类型转换为普通IEnumerable并使用反射调用在ClientIEnumerable返回的object对象调用方法。

由于所有内容都在您动态加载的DLL中,因此首先想到的是将GetAll强制转换为IEnumerable<dynamic>并相应地使用这些属性。

您将永远无法创建通用的IEnumerable <'Customer>对象,因为运行时无法在编译时静态检查类的属性。

我打算发布关于动态物体的文章,但Brizio打败了我。 另一个可能对你有帮助的想法。

您可以创建一个CustomerProxy类(在控制台应用程序中),它公开客户的公共方法,并使用反射调用Customer对象。 这样可以为CustomerProxy类的用户进行静态类型检查。

http://msdn.microsoft.com/en-us/library/vstudio/dd799517(v=vs.100).aspx在泛型中搜索协方差和逆变

IEnumerable<Object> customerList = methodInfo.Invoke(customerRepository, null);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM