Issue
Based on the requirement I need to pass a dynamically generated property name for the dynamic object below.
var dynamicObj = new { State = "Caifornia" };
Instead of State I should be able to pass any name. Here is my code so far. Everything works but I cannot figure it out how to make the property name dynamic. Something like var dynamicObj = new { "State" = "Caifornia" };
var rule = new Rule("State", "NotEqual", "Florida");
var dynamicObj = new { State = "Caifornia" };
var expression = Expression.Parameter(dynamicObj.GetType(), "State");
var property = Expression.Property(expression, "State");
var propertyType = dynamicObj.GetType().GetProperty(rule.MemberName).PropertyType;
var isValid = false;
ExpressionType tBinary;
if (Enum.TryParse(rule.Operator, out tBinary))
{
var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, propertyType));
var result = Expression.MakeBinary(tBinary, property, right);
var func = typeof(Func<,>).MakeGenericType(dynamicObj.GetType(), typeof(bool));
var expr = Expression.Lambda(func, result, expression).Compile();
isValid = (bool)expr.DynamicInvoke(dynamicObj);
}
return isValid;
Solution
Not sure you can do that with anonymous types, but you can do that with ExpandoObject, like this:
var rule = new Rule("State", "NotEqual", "Florida");
var dynamicObj = (IDictionary<string, object>) new ExpandoObject();
dynamicObj.Add("State", "California");
var expression = Expression.Parameter(typeof(object), "arg");
// create a binder like this
var binder = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, "State", null, new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
});
// define dynamic property accessor
var property = Expression.Dynamic(binder, typeof(object), expression);
// the rest as usual
var isValid = false;
ExpressionType tBinary;
if (Enum.TryParse(rule.Operator, out tBinary))
{
var right = Expression.Constant(rule.TargetValue);
var result = Expression.MakeBinary(tBinary, property, right);
var func = typeof(Func<,>).MakeGenericType(dynamicObj.GetType(), typeof(bool));
var expr = Expression.Lambda(func, result, expression).Compile();
isValid = (bool)expr.DynamicInvoke(dynamicObj);
}
Answered By - Evk Answer Checked By - Mary Flores (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.