vendredi 22 mai 2015

I have a third party library that is similar to this implementation:

public class Mapper<T>
{
 public virtual MapperdType Map(Expression<Func<T, object>> expression);
}

This is ran to map properties of my class

public class Person
{
 public string Name { get; set; }
 public string Phone {get; set; }
}

to certain names by

public class MyMapper : Mapper<Person>
{
  Map(m => m.Person).Name("FunkyName");
  Map(m => m.Phone).Name("FunkyPhone");
}

My goal is create a mapper like this a generic class T that will map property names into other strings with certain rules and convention through reflection. I largely succeeded:

PropertyInfo classProperty = ... // doesn't matter
string propName = classProperty.Name;

ParameterExpression parameter = Expression.Parameter(typeof(T), "m");
MemberExpression property = Expression.Property(parameter, propName);

var quariableType = typeof(IQueryable<>).MakeGenericType(classProperty.PropertyType);
var delegateType = typeof(Func<,>).MakeGenericType(typeof(T), quariableType);

LambdaExpression lambda= Expression.Lambda(property, parameter);

var mapMethod = this.GetType()
     .GetMethod("Map", new[] { typeof(Expression<Func<T, object>>) });

the problem is when I invoke the method with my computed lambda expression

mapMethod.Invoke(this, new[] { lambda });

it throws an exception saying that it cannot covert my constructed lamda which happened to be of type Expression<Func<T, string>> into Expression<Func<T, object>> or whatever the type of classProperty happens to be.

When I call explicitly Map(p => p.Name) it works fine although object is expected and string is converted into object but when I do this through reflection it does not accept this type specific lambda and wants queryable type to have object in it.

Any suggestion how to add cast into reflection ?





Aucun commentaire:

Enregistrer un commentaire