Recommendations for comparing one object with another

My question is: what is the best way I can map one object to another in the most convenient way. I cannot change the way in which the Dto object we get is more normalized, so I need to create a way to map this to our implementation of their object.

Here is a sample code to show what I need:

class Program { static void Main(string[] args) { var dto = new Dto(); dto.Items = new object[] { 1.00m, true, "Three" }; dto.ItemsNames = new[] { "One", "Two", "Three" }; var model = GetModel(dto); Console.WriteLine("One: {0}", model.One); Console.WriteLine("Two: {0}", model.Two); Console.WriteLine("Three: {0}", model.Three); Console.ReadLine(); } private static Model GetModel(Dto dto) { var result = new Model(); result.One = Convert.ToDecimal(dto.Items[Array.IndexOf(dto.ItemsNames, "One")]); result.Two = Convert.ToBoolean(dto.Items[Array.IndexOf(dto.ItemsNames, "Two")]); result.Three = dto.Items[Array.IndexOf(dto.ItemsNames, "Three")].ToString(); return result; } } class Dto { public object[] Items { get; set; } public string[] ItemsNames { get; set; } } class Model { public decimal One { get; set; } public bool Two { get; set; } public string Three { get; set; } } 

I think it would be great if I had some kind of matching class that would take in the model propertyInfo objects, the type I want to convert, and the "itemname" I want to pull out. Does anyone have any suggestions to make this cleaner?

Thank!

+29
c # design-patterns mapping
Apr 20 '13 at 7:57
source share
3 answers

I would choose AutoMapper , an open source library and free mapping that allows you to map one type to another based on conventions (i.e. display public properties with the same name and the same / derived / convertible types, as well as many other smart ) Very easy to use, allow you to achieve something like this:

 Model model = Mapper.Map<Model>(dto); 

Not sure about your specific requirements, but AutoMapper also supports custom variable values that should help you write a single, generic implementation of your specific cartographer.

+21
Apr 20 '13 at 10:02
source share

This is a possible general implementation using the reflection bit (pseudo code, now no VS):

 public class DtoMapper<DtoType> { Dictionary<string,PropertyInfo> properties; public DtoMapper() { // Cache property infos var t = typeof(DtoType); properties = t.GetProperties().ToDictionary(p => p.Name, p => p); } public DtoType Map(Dto dto) { var instance = Activator.CreateInstance(typeOf(DtoType)); foreach(var p in properties) { p.SetProperty( instance, Convert.Type( p.PropertyType, dto.Items[Array.IndexOf(dto.ItemsNames, p.Name)]); return instance; } } 

Using:

 var mapper = new DtoMapper<Model>(); var modelInstance = mapper.Map(dto); 

This will be slow if you create an instance of mapper, but much faster.

+5
Apr 20 '13 at 8:30
source share
 /// <summary> /// map properties /// </summary> /// <param name="sourceObj"></param> /// <param name="targetObj"></param> private void MapProp(object sourceObj, object targetObj) { Type T1 = sourceObj.GetType(); Type T2 = targetObj.GetType(); PropertyInfo[] sourceProprties = T1.GetProperties(BindingFlags.Instance | BindingFlags.Public); PropertyInfo[] targetProprties = T2.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var sourceProp in sourceProprties) { object osourceVal = sourceProp.GetValue(sourceObj, null); int entIndex = Array.IndexOf(targetProprties, sourceProp); if (entIndex >= 0) { var targetProp = targetProprties[entIndex]; targetProp.SetValue(targetObj, osourceVal); } } } 
+2
Jun 22 '17 at 19:35
source share



All Articles