Type conversion – Using Expression in place of reflection ( C#.net )

Posted on March 24, 2009. Filed under: Expression |


Here I write a very simple method (you can make it more generic if you want) that get source object, target Type and a dictionary. First two parameters need not any explanation and the dictionary contains the mapping definition where the key holds the target type properties and value holds the source type properties. If value is empty or null that means that should not be mapped (If you don’t want to map any particular property You can also delete the element from dictionary). 

private static object ConvertTo(object source, Type targetType, Dictionary propertyMapDictionary)
{
    //create a instance of target object
    object target = Activator.CreateInstance(targetType);

    if (target != null && null != propertyMapDictionary && propertyMapDictionary.Count > 0)
    {
        //determine the source type
        Type sourceType = source.GetType();
        foreach (var item in propertyMapDictionary.Keys)
        {
            if (propertyMapDictionary.ContainsKey(item)
            && propertyMapDictionary[item] != null
            && propertyMapDictionary[item] != string.Empty)
            {
                //Initialize parameter expresssions for getter method
                System.Linq.Expressions.ParameterExpression param = System.Linq.Expressions.Expression.Parameter(typeof(Object), "param");
                System.Linq.Expressions.Expression convertedParam = System.Linq.Expressions.Expression.Convert(param, sourceType);
                System.Linq.Expressions.LambdaExpression GetPropertyValueExp = System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression.Property(convertedParam, propertyMapDictionary[item]), param);
                //Create dynamic getter Delegate
                Delegate dynamicGetter = GetPropertyValueExp.Compile();

                //Get property info target type
                PropertyInfo ITargetPInfo = targetType.GetProperty(item, BindingFlags.Public | BindingFlags.Instance);
                //Determmine set method
                MethodInfo SetterMethodInfo = ITargetPInfo.GetSetMethod();
                //Initialize the parameter- expressions for setter method
                System.Linq.Expressions.ParameterExpression paramo = System.Linq.Expressions.Expression.Parameter(targetType, "param");
                System.Linq.Expressions.ParameterExpression parami = System.Linq.Expressions.Expression.Parameter(ITargetPInfo.PropertyType, "newvalue");
                System.Linq.Expressions.MethodCallExpression MethodCallSetterOfProperty = System.Linq.Expressions.Expression.Call(paramo, SetterMethodInfo, parami);
                System.Linq.Expressions.LambdaExpression SetPropertyValueExp = System.Linq.Expressions.Expression.Lambda(MethodCallSetterOfProperty, paramo, parami);
                //Create a dynamic setter Delegate
                Delegate dynamicSetter = SetPropertyValueExp.Compile();
                //Invoke getter method and get the source property value
                object actualValue = dynamicGetter.DynamicInvoke(source);
                //Invoke setter method and set the target property value
                dynamicSetter.DynamicInvoke(target, System.Convert.ChangeType(actualValue, ITargetPInfo.PropertyType));
            }//end if
        }//end foreach
    }
    return target;
}        

Its basically map only those properties that is found in dictionary (Mapping definition) and pick up value and set it to the target object .Here I didn’t do any datatype check for the mapped property. What I am trying to do here , I just use expression to fetch attribute value and set it to target object .

Advertisements

Make a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Liked it here?
Why not try sites on the blogroll...

%d bloggers like this: