In our project we’re AutoMapper to transform a list of name – value pairs to objects with properties. It pivots by mapping the name of the pair to the property and assigning the value to it.
We created an extension method that takes a Func to return the Name and a Func to return the Value. The configuration is very short when using this extension method. See the listing below
Mapper.CreateMap<List<Data>, Person>() .ConvertFromList(x => x.Name, x => x.Value);
The List with Data objects is the name-value pairs, where Person is the actual object with the properties mapped by the name.
The extension method looks impressive, but that is because of the Name and Value Func and not because of the complexity.
public static IMappingExpression<List<TSource>, TDest> ConvertFromList<TSource, TDest>( this IMappingExpression<List<TSource>, TDest> exp, Func<TSource, string> name, // Function to return the Name Func<TSource, object> value) // Function to return the Value { var allPropertyFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; foreach (var prop in typeof(TDest).GetProperties(allPropertyFlags)) { // map with value (implicit conversion) of the first item with Name equal to the property name exp.ForMember(prop.Name, map => map.MapFrom(src => value(src.First(s => name(s) == prop.Name)))); // only when name exists will there be mapped exp.ForMember(prop.Name, map => map.Condition(src => src.Any(s => name(s) == prop.Name))); } return exp; }
We’re happy with the current configuration, but we think case sensitivity could get an issue.
References
AutoMapper Dictionary Flattening on stackoverflow, origional source for our solution