C# AutoMapper 動態映射 嵌套對象映射 嵌套集合映射


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可以運用到數據動態同步.可選字段的同步

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM