zoukankan      html  css  js  c++  java
  • 让AutoMapper更好用

    AutoMapper

    Dto与EF实体之间的转换用AutoMapper会变的很方便、很高效,是大多数项目的选择。博主本人的项目也在使用AutoMapper这个组件

    好用归好用,但是想要把它用好又是另一事了。AutoMapper需我们去配置映射才可以去进行Map转换,下面有Person类与对应的Dto类

    public class Person
        {
            public string Name { get; set; }
    
            public string Age { get; set; }
        }
    
        public class PersonDto
        {
            public string Name { get; set; }
    
            public string Age { get; set; }
        }

    按照官方使用方式,我们需要以下几个步骤

             //配置映射
                Mapper.Initialize(o =>
                {
                    o.CreateMap<Person, PersonDto>();
                    o.CreateMap<PersonDto, Person>();
                });
                var p = new Person { Age = "20", Name = "小明" };
                //进行转换
                var pDto = Mapper.Map<PersonDto>(p);

    当然,上面的使用方式没有什么问题,似乎也很简单。但是对于一个项目来说几十成百的表已经是家常便饭,对于种配置方式会不会很蛋疼呢。想象一些一堆的CreateMap就会让人恶心,我也看到现在有一些解决方案,即对映射进行粒化每一个相关的功能或实体创建Profile类,添加到Profile集合中。在程序运行时统一注册。这样也不错,但是还是会去写一堆的Profile类和CreateMap。

    使用Atturibute进行配置映射

    在abp中看到了使用特性的方式进行配置映射,简单的一行代码就可以解决问题,但是似乎在没有使用abp的项目里并不是那么使用这种方式,所以我就借鉴了这种方法写了一个属于自己的特性

    [AutoMapFrom(typeof(Person))]

    首先是创建一个类去继承自Attribute,这是很简单的。在实际项目中不一定都是一个实体对应一个dto的情况,还会有一个实体对应多个dto的情况存在,所以toSource应该是一个数组

    public class AutoMapAttribute : Attribute
        {
            public Type[] ToSource { get; private set; }
    
            public AutoMapAttribute(params Type[] toSource)
            {
                this.ToSource = toSource;
            }
        }

    后面的代码就更为简单了,我们拿到DTO的程序集,(视项目程序集名而定) ,然后拿到所有的自定义类型判断其中的type是否有贴上了AutoMapAttribute类,如果有的话,创建它的实例,拿到source,然后进行创建映射。很简单对吧。

    public class AutoMapperModule
        {
            public static void Init()
            {
                //拿到dto程序集
                var asm = Assembly.Load("DTO");
    
                //拿到自定义的类型
                var types = asm.GetExportedTypes();
                //创建映射
                Mapper.Initialize(o =>
                {
                    foreach (var type in types)
                    {
                        //判断是否贴上了AutoMapAttribute
                        if (!type.IsDefined(typeof(AutoMapAttribute))) continue;
                        var autoMapper = type.GetCustomAttribute<AutoMapAttribute>();
    
    
                        foreach (var source in autoMapper.ToSource)
                        {
                            o.CreateMap(type, source);
                            o.CreateMap(source, type);
                        }
                    }
                });
            }
        }

    最后我们需要在程序启动时去加载这些配置,一切就大功告成了。

           protected void Application_Start()
            {
                //初始化AutoMapper
                AutoMapperModule.Init();
            }

    Map的转换

    官网提供的方式是使用Mapper.Map的方式进行转换,假如有一天出现一个更吊,速度更快的开源组件。这个时候我们的项目已经和AutoMapper产生了严重的依赖导致替换会变的很吃力,而且Mapper.Map这种方式也并不是那么的简洁好用。所以写一个Map是势在必行的

    我想要的是方式是在对象上直接点出Map并且使用泛型选择我要转换后的类型,这时候已经想到可以用扩展方法了,是不是很方便呢

    public static class AutoMapExtension
     {
    
            public static TDestination MapTo<TDestination>(this object source)
            {
                return Mapper.Map<TDestination>(source);
            }
    
            public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
            {
                return Mapper.Map(source, destination);
            }
    }
    static void Main(string[] args)
            {
    
                //配置映射
                Mapper.Initialize(o =>
                {
                    o.CreateMap<Person, PersonDto>();
                    o.CreateMap<PersonDto, Person>();
                  
                });
                var p = new Person { Age = "20", Name = "小明" };
                //进行转换
                p.MapTo<PersonDto>();
            }
  • 相关阅读:
    BZOJ3252攻略——长链剖分+贪心
    BZOJ3522[Poi2014]Hotel——树形DP
    BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
    BZOJ3626[LNOI2014]LCA——树链剖分+线段树
    BZOJ2157旅游——树链剖分+线段树
    BZOJ3531[Sdoi2014]旅行——树链剖分+线段树
    BZOJ2243[SDOI2011]染色——树链剖分+线段树
    zookeeper(1)初识zookeeper
    任督二脉
    RPC框架之RMI
  • 原文地址:https://www.cnblogs.com/LiangSW/p/AutoMapper.html
Copyright © 2011-2022 走看看