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)
 
 Posts
Posts
 
 
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.