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可以运用到数据动态同步.可选字段的同步