Ian Dillon Ian Dillon - 1 year ago 220
C# Question

How to invoke a method accepting linq expression arguments

hi this is my method which exists as part of a generic entity framework repository class.

public IList<T> GetAll(params Expression<Func<T, object>>[] navigationProperties)
List<T> list;

IQueryable<T> dbQuery = Context.Set<T>();

//Apply eager loading
foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
dbQuery = dbQuery.Include<T, object>(navigationProperty);

list = dbQuery
return list;

I need to call the method via reflection and this is what I have done so far.

using (var ctx = (DbContext)Activator.CreateInstance(dbContextType))
ctx.Configuration.LazyLoadingEnabled = false;

var curEntityPI = ctx.GetType().GetProperties().Where(pr => pr.Name == "Worker").First();
var curEntityType = curEntityPI.PropertyType.GetGenericArguments().First();
var set = ctx.Set(curEntityType);
Type generic = typeof(DataAccess.Repository.EF.dEfDataRepository<,>);
Type[] typeArgs = {curEntityType, dbContextType};
Type constructed = generic.MakeGenericType(typeArgs);
MethodInfo methodInfo = constructed.GetMethod("GetAll");

object repositoryInstance = Activator.CreateInstance(constructed, new object[] { ctx });
var result = methodInfo.Invoke(repositoryInstance,new object[] { });

I know I need to change the parameter array in methodInfo.Invoke, but for test purposes say it was just an empty linq expression or the equivalent of this when called statically ..

WorkerRepository workerRepositoryInstance = new
List<Worker> workers = workerRepositoryInstance.GetAll().ToList();

How would I supply the correct parameter in methodInfo.Invoke()

I am doing this because I need to work with a dbcontext and entities which are in an external dll and can't add a reference to this in my application project. My application needs to able reference the 'satellite' assembly in a way that different deployments of the application can access different versions of the data provider dll.

Thanks a lot for your help.

Answer Source

If I understand correctly, you need to create dynamically an empty array of Expression<Func<T, object>>.

You can use Array.CreateInstance method for that:

var navigationPropertyType = typeof(Expression<>).MakeGenericType(
    typeof(Func<,>).MakeGenericType(curEntityType, typeof(object)));

var navigationProperties = Array.CreateInstance(navigationPropertyType, 0);

var result = methodInfo.Invoke(repositoryInstance, new object[] { navigationProperties });
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download