访问IEnumerable从通过反射调用的方法返回

本文关键字:调用 反射 方法 返回 IEnumerable 访问 | 更新日期: 2023-09-27 18:15:55

我有一个。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类型)。

我怎样才能访问客户列表,以便访问客户属性,而不必显式地引用.dll ?

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

你有三个选择

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

由于所有内容都在动态加载的DLL中,因此首先想到的也是最快的事情就是将GetAll转换为IEnumerable<dynamic>并相应地使用属性。

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

我本来打算发一篇关于动态对象的文章,但是Brizio抢先了我一步。另一个主意可能对你有帮助。

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

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

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