简体   繁体   中英

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

I have a .dll and a console app that uses the said .dll but doesn't reference directly, it loads it via reflection. The console app calls a method of a class inside the .dll.
The method signature is IEnumerable<Customer> GetAll() ;

In the .dll I have done this:

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

In the Console app I've done this:

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

Now the question is, since GetAll returns IEnumerable<Customer> and my console app doesn't "know" anything about MyDLL.dll (I don't reference it directly, so it doesn't knows the Customer type).

How can I access to the Customer list in order to access Customer'a properties without having to make a reference to the .dll explicitly?

You have three options

  1. Move Client or move a interface Client implements to a 3rd dll that both the reflected DLL and your console app can reference.
  2. Use the dynamic keyword as the type of the object ( dynamic customerList = methodInfo.Invoke(... ), this is the exact situation it was invented for.
  3. Cast the return type as a plain IEnumerable and use reflection calls to call the methods in Client on the object objects the IEnumerable returns.

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

You will never be able to make a generic IEnumerable<'Customer> object because the runtime can not statically check the properties of the class at compile time.

I was going to post about dynamic objects, but Brizio beat me to it. One other idea which might help you.

You could make a CustomerProxy class (in the console app) which exposes the public methods of customer, and invokes the Customer objects using reflection. This has the benefit of static type checking for users of the CustomerProxy class.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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