favner85
favner85

Reputation: 63

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?

Upvotes: 5

Views: 353

Answers (4)

dimzon
dimzon

Reputation: 424

http://msdn.microsoft.com/en-us/library/vstudio/dd799517(v=vs.100).aspx or search for Covariance and Contravariance in Generics

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

Upvotes: 0

astallaslions
astallaslions

Reputation: 321

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.

Upvotes: 1

Scott Chamberlain
Scott Chamberlain

Reputation: 127573

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.

Upvotes: 5

LazyOfT
LazyOfT

Reputation: 1438

As everything is inside the DLL that you load dynamically, the first and fastest thing that comes to mind is to cast the GetAll as an IEnumerable<dynamic> and use the properties accordingly.

Upvotes: 1

Related Questions