Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an Expression<Func<,>> using reflection

Im using Moq to create mocks of a data set.

I have created a little helper class that allows me to have an in memory storage instead of a database that makes unit testing a breeze. That way I can add and remove items from my mock data set, this allows me to test my insert and delete service calls.

During the setup of the mock I have a line that looks like the following

this.Setup(i => i.AcademicCycles).Returns(mockStore.GetList<AcademicCycle>()); 

My mock has a lot of properties so I would like to perform this setup step using reflection. I have managed to the Returns part of the process working via reflection but I am stuck on the lambda method to Setup.

Setup takes an

Expression<Func<GoalsModelUnitOfWork, IQueryable<AcademicCycle>>> that corresponds to the i => i.AcademicCycles

and I would like to create this dynamically. Using reflection I have the following:

The name of the property: "AcademicCycles"

The type IQueryable<AcademicCycle>

The type AcademicCycle

I also have the instance of the i in the lambda statement which is a GoalsModelUnitOfWork

like image 566
Aran Mulholland Avatar asked May 23 '12 02:05

Aran Mulholland


1 Answers

The code to create the expression dynamically would be like this:

ParameterExpression parameter = Expression.Parameter(typeof (GoalsModelUnitOfWork), "i"); MemberExpression property = Expression.Property(parameter, "AcademicCycles");  var queryableType = typeof (IQueryable<>).MakeGenericType(typeof (AcademicCycle)); var delegateType = typeof (Func<,>).MakeGenericType(typeof (GoalsModelUnitOfWork), queryableType);  var yourExpression = Expression.Lambda(delegateType, property, parameter); 

The result will have the desired type, but the problem is that the return type of Expression.Lambda() is LambdaExpression and you can't perform a type cast to Expression<Func<...>> to pass it as parameter to your setup function because you don't know the generic type parameters for the Func. So you have to invoke the Setup method by reflection, too:

this.GetType().GetMethod("Setup", yourExpression.GetType()).Invoke(this, yourExpression); 
like image 159
fero Avatar answered Oct 04 '22 10:10

fero