Skip to main content
3 of 3
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/

Class naming

I needed a class to assign values to a property of an object

this can be reworded to

I needed a class to map values to a property of an object

which results in IPropertyMapper and DynamicPropertyMapper.


public void Assign(T target, string propertyName, object value)

You are doing null checks at the top of the method which is very good.

Because the propertyName will be passed to the PropertiesMatch() method which could throw an AmbiguousMatchException you should either enclose this call into a try..catch or the call to GetProperty() inside the PropertiesMatch() method. See the remarks in the docu.

You should also state in the xml documentation that the propertyName parameter is used case-sensitive.

Speaking of xml documentation, you are missing a to after used

/// Dynamically creates an Action that will be used assign a value to the target's property and adds it to the map.  

//This is necessary because we hold a Action<T,object>.
  var convertedValue = Expression.Convert(valueParameter, propertyType);

I love this comment because it is clearly telling why you are doing this.


In the CreateAndAddAssignExpression() method you are adding the Action<> as a value to the Dictionary<> but you are returning the action as well. Why don't you rename the method to CreateMappingExpression(), skip the adding to the dictionary and add the result to the Dictionary() where you call it ?

For the constructor this would be

        foreach (var property in properties)
        {
            var action = CreateMappingExpression(property.Name, property.PropertyType);
            _expressionMap.Add(property.Name, action);
        }  

and in the Assign() method like so

     if(_lazyPopulate && !_expressionMap.TryGetValue(propertyName, out assignExpression))
     {
         if (PropertiesMatch(value.GetType(), propertyName))
         {
             assignExpression = CreateMappingExpression(propertyName, value.GetType());
         }

         _expressionMap.Add(propertyName, assignExpression);
     }  

You see this would remove the else part and also makes the comment //Add null to show we checked that this property doesn't exist in T, so we skip the checks the next time. redundant.

But as Oguz Ozgul pointed out in his answer you have a problem if _lazyPopulate == false in the way this condition is used. If we revert the condition to check TryGetValue() first it won't work without problems but at least without exceptions like so

     if(!_expressionMap.TryGetValue(propertyName, out assignExpression) && _lazyPopulate)
     {
         if (PropertiesMatch(value.GetType(), propertyName))
         {
             assignExpression = CreateMappingExpression(propertyName, value.GetType());
         }

         _expressionMap.Add(propertyName, assignExpression);
     }  
Heslacher
  • 50.4k
  • 5
  • 81
  • 175