AutoMapper支持Dynamic 映射,Dynamic Deep 映射.
代碼:
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Dynamic; using System.Linq; using System.Text; using System.Threading.Tasks; using AutoMapper; using Newtonsoft.Json; namespace ConsoleApp1 { class SubSetting { public int SubTimeout { get; set; } public string SubColour { get; set; } } class Settings { public int Timeout { get; set; } public string Colour { get; set; } public SubSetting SubSettings { get; set; } public List<SubSetting> SubSettingList { get; set; } } public static class DynamicExtensions { public static dynamic ToDynamic(this object value) { IDictionary<string, object> expando = new ExpandoObject(); foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType())) { object val = property.GetValue(value); if ((property.PropertyType.IsGenericType || property.PropertyType.Name.Contains("[]")) && val is IEnumerable<object>) { var values = val as IEnumerable<object>; List<ExpandoObject> result = new List<ExpandoObject>(); foreach (var v in values) { result.Add(v.ToDynamic()); } expando.Add(property.Name, result); } else if (property.PropertyType.Name.Contains("Anonymous")) { expando.Add(property.Name, val.ToDynamic()); } else { expando.Add(property.Name, val); } } return expando as ExpandoObject; } } class Program { static void Main(string[] args) { dynamic baseSettings = new ExpandoObject(); baseSettings.Timeout = 1; baseSettings.Colour = "Red"; baseSettings.SubSettings = new ExpandoObject(); baseSettings.SubSettings.SubTimeout = 11; baseSettings.SubSettings.SubColour = "Green"; baseSettings.SubSettingList = new List<ExpandoObject>(); dynamic SubSettings1 = new ExpandoObject(); SubSettings1.SubTimeout = 15; SubSettings1.SubColour = "big1"; dynamic SubSettings2= new ExpandoObject(); SubSettings2.SubTimeout = 16; SubSettings2.SubColour = "big2"; (baseSettings.SubSettingList as List<ExpandoObject>).Add(SubSettings1); (baseSettings.SubSettingList as List<ExpandoObject>).Add(SubSettings2); //改寫 dynamic overrideSettings = new ExpandoObject(); overrideSettings.Timeout = 2; overrideSettings.SubSettings = new ExpandoObject(); overrideSettings.SubSettings.SubTimeout = 99; var config = new MapperConfiguration(cfg => { }); var mapper = config.CreateMapper(); var settings = mapper.Map<Settings>(baseSettings); Console.WriteLine(JsonConvert.SerializeObject(settings)); mapper.Map(overrideSettings, settings); Console.WriteLine(JsonConvert.SerializeObject(settings)); var anonymousData = new { SubSettingList = new Collection<dynamic> // 或者 new [] , new List<dynamic> 都可以 { new {SubTimeout=95, SubColour="bbz1"}, new {SubTimeout=96, SubColour="bbz2"} }, Timeout =88, Colour="bb", SubSettings = new { SubTimeout = 89, SubColour = "bbSub" } }; var d2 = anonymousData.ToDynamic(); var settings2 = mapper.Map<Settings>(d2); Console.WriteLine(JsonConvert.SerializeObject(settings2)); Console.ReadKey(); } } }
演示代碼中包含了嵌套類,嵌套集合類.
匿名嵌套,匿名集合嵌套.
對於anonymous的匿名類,直接使用AutoMapper映射會報錯,這里使用了匿名類轉ExpandoObject來保證AutoMapper的穩定運行.
在擴展方法ToDynamic中,適配了嵌套對象,嵌套集合對象的轉換.保證子類集合可以正常使用.
此Demo可以運用到數據動態同步.可選字段的同步