利用AutoMapper实现数据实体类之间的转换


在分解复杂的软件系统时,软件设计者用得最多的技术之一就是分层。分层右很多优点:如提高复用性、较低耦合性,但也有其缺陷所在:如过多的层次会影响性能、有时会为我们带来级联修改。

会带来级联修改怎么理解呢?例如需求变化要增加一个在用户界面上显示的数据域,就必须在数据中增加相应字段,还必须在用户界面和数据库之间的每一层做相应的修改。在不同层次中会有不同的数据实体类(有些类还包括一些方法),这些实体类之间为了实现数据传递就必须进行类之前的转换,这样的转换可以手写代码进行一对一的转换完成任务,就像下图一样,并且你还得为对应的List类书写相应的转换方法,有木有更简单方便的方案呢?这就要说到标题里写的AutoMapper,从名字可以看出这是一款用于映射的工具。

直接上代码,第一先定义需要进行转换的实体类,第二步是继承Profile接口,进行注册。

using AutoMapper;

namespace WindowsFormsApp1
{
    /// 
    /// 模仿需要转换的数据实体类
    /// 
    public class Source
    {
        public int SomeValue { get; set; }
        public string AnotherValue { get; set; }
    }

    /// 
    /// 模仿需要转换的数据实体类
    /// 
    public class Destination
    {
        public int SomeValue { get; set; }
    }

    /// 
    /// 通过Profile注册
    /// 告诉AutoMapper需要进行哪些类的转换,如果A转换成B,B也要转换成A,那就需要写两条
    /// 
    public class SourceProfile : Profile
    {
        public SourceProfile()
        {
            CreateMap();
            CreateMap();
        }
    }
}

第三步是将Profile中书写的映射关系添加到Mapper实例,常规需要书写一个方法用于获取唯一的Mapper实例(单例模式),实例中配置了映射关系。

using AutoMapper;

namespace WindowsFormsApp1
{
    public class AutoMapperConfigure
    {
        public static IMapper GetMapper()
        {
            var config = new MapperConfiguration(cfg =>
            {
                // 扫描当前程序集
                cfg.AddMaps(System.AppDomain.CurrentDomain.GetAssemblies());
            });

            var mapper = config.CreateMapper();
            return mapper;
        }
    }
}

第四步具体调用,默认情况下,AutoMapper 基于相同的字段名映射,并且是 不区分大小写 的。也可以通过修改配置,实现AutoMapper提供的命名规则映射。LowerUnderscoreNamingConventionPascalCaseNamingConvention 是 AutoMapper 提供的两个命名规则。前者命名是小写并包含下划线,后者就是帕斯卡命名规则(每个单词的首字母大写)。

        private void promptMessageButton_Click(object sender, EventArgs e)
        {
            Source source = new Source()
            {
                SomeValue = 1,
                AnotherValue = "Another"
            };

            var mapper = AutoMapperConfigure.GetMapper();
            Destination destination = mapper.Map(source);
            MessageBox.Show(destination.SomeValue.ToString());
        }

像最开始截图那种比较复杂的涉及枚举和枚举描述之间转换,甚至List转换成string,也可以用AutoMapper实现。可以对转换的成员属性调用写好的静态方法,来实现按规则的准换,如下图。

参考资料:https://www.cnblogs.com/gl1573/p/13098031.html

有兴趣的同学还可以看一下官方文档,还有样例:https://docs.automapper.org/en/latest/

看了博客的同学建议还是自己动手写一下,借用荀子的一句话:不闻不若闻之,闻之不若见之,见之不若知之,知之不若行之。有疑问欢迎与我讨论。