Reputation: 19
i am new to reflection and hope you can help me out. I find a lot questions similar to mine but does not get it transmitted on my Problem.
I have a method:
IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, object>> propertyNameExpression, object propertyValue) where TEntity : NT.Base.Framework.ODL.Entity;
I normally call this Method like this:
PersistentService.Get<Agent>(a => a.ID, Guid.Empty);
But now i know it only at run time which class i have. So i have a
Type classType;
And need to know how to call this method with the classType. I have a temporary solution, where i take the method with a string but hardcoded strings in code are not so nice.
MethodInfo methodInfo = typeof(PersistenceService).GetMethod("Get", new Type[] { classType, typeof(string) });
var classMethod = methodInfo.MakeGenericMethod(classType);
string query = "SELECT * FROM " + classType.Name + " WHERE " + classType.Name + ".Id = '" + pg.GUID.ToString() + "'";
dynamic dEnumeration = classMethod.Invoke(PersistenceService, new object[] { query });
dynamic dEntity = Enumerable.FirstOrDefault(dEnumeration);
Edit: I tried the following but methodInfo is always NULL
ParameterExpression parameter = Expression.Parameter(typeof(Entity), "a");
var delegateType = typeof(Func<,>).MakeGenericType(typeof(Entity), typeof(object));
var yourExpression = Expression.Lambda(delegateType, parameter, parameter);
MethodInfo methodInfo = typeof(PersistenceService).GetMethod("Get", new Type[] { yourExpression.GetType(), typeof(object) });
The Type of yourExpression.GetType() is:
{Name = "Expression`1" FullName = "System.Linq.Expressions.Expression`1[[System.Func`2[[NT.Base.Framework.ODL.Entity, NT.Base.Framework.ODL, Version=0.0.0.126, Culture=neutral, PublicKeyToken=null],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"} System.Type {System.RuntimeType}
So please help me, how to get and invoke this method.
Upvotes: 1
Views: 1700
Reputation: 19
I got it by my own:
ParameterExpression parameter = Expression.Parameter(classType, "a");
//a.Id GUID
MemberExpression property = Expression.Property(parameter, "Id");
//a.ID as object
var newProp = Expression.TypeAs(property, typeof(object));
var delegateType = typeof(Func<,>).MakeGenericType(classType, typeof(object));
var yourExpression = Expression.Lambda(delegateType, newProp, parameter);
MethodInfo methodInfo = typeof(PersistenceService).GetMethods()
.Where(x => x.Name == "Get")
.Select(x => new { M = x, P = x.GetParameters() })
.Where(x => x.P.Length == 2
&& x.P[0].ParameterType.IsGenericType
&& x.P[0].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)
&& x.P[1].ParameterType == typeof(object))
.Select(x => new { x.M, A = x.P[0].ParameterType.GetGenericArguments() })
.Where(x => x.A[0].IsGenericType
&& x.A[0].GetGenericTypeDefinition() == typeof(Func<,>))
.Select(x => new { x.M, A = x.A[0].GetGenericArguments() })
.Where(x => x.A[0].IsGenericParameter
&& x.A[1] == typeof(object))
.Select(x => x.M)
.SingleOrDefault();
if(methodInfo != null)
{
MethodInfo method = methodInfo.MakeGenericMethod(classType);
dynamic dEnumeration = method.Invoke(PersistenceService, new object[] { yourExpression, pg.GUID });
dynamic dEntity = Enumerable.FirstOrDefault(dEnumeration);
...
Upvotes: 1