zoukankan      html  css  js  c++  java
  • AutoMapper在C#中的有趣应用

    最近发现了一个比较有趣的东西 AutoMapper,主要将Model转换为DTO,DTO更注重数据,对领域对象进行合理封装,从而不会将领域对象的行为过分暴露给表现层。

    先来看一点实例,两个类之间的映射。

    首先定义两个类Source与DTOSource:

     1  public class Source
     2     {
     3         public int Id { get; set; }
     4         public string Content { get; set; }
     5     }
     6 
     7     public class DTOSource
     8     {
     9         public int Id { get; set; }
    10         public string Content { get; set; }
    11     }

     Source与DTOSource字段完全相同,来看看它俩如何通过AutoMapper转换,代码很简单。

    1 Mapper.Initialize(x=>{
    2      x.CreateMap<Source,DTOSource>();
    3 });
    4 
    5 Source s = new Source{Id=1,Content="123"};
    6 
    7 DTOSource dto = Mapper.Map<DTOSource>(s);

    第一步建立Source到DTOSource之间的映射,初始化一个Source实例后,来看下执行结果:

    执行完成后,可以看到dto中的数据与之前初始化的s的数据是一样的,就像是直接将s拷贝了一份给dto,在两个类字段名定全相同的情况下如此,那么如果DTOSource中的字段名与Source中的不相同如何,其实也很简单,只需

    要改成一点点的代码既可:

    我们将DTOSource中的Content的字段名改成Desc,此时只需要建立映射关系时,指定字段就可以了:

    1 Mapper.Initialize(x => {
    2    x.CreateMap<Source, DTOSource>().ForMember(c=>c.Desc,q=> {
    3       q.MapFrom(z => z.Content);
    4      });
    5 });

    来看看运行结果如何;

    可以看到与之前的运行结果是相同的。

    那么如何映射两个List,其实也很简单,和上述代码几乎可以说是无差别,只是在最后一步时,要做一点点的修改就可以了。如下面代码:

     1  Mapper.Initialize(x => {
     2                 x.CreateMap<Source, DTOSource>().ForMember(c => c.Desc, q =>
     3                 {
     4                     q.MapFrom(z => z.Content);
     5                 });
     6             });
     7 
     8             s.Add(new Source { Id = 1, Content = "123" });
     9 
    10             var dto = Mapper.Map<List<DTOSource>>(s);

    可以看到除了最后一句代码,其它几乎是完全相同的,只是在最后一句代码中,目标类型改成了List<DTOSource>仅此而已。看下运行结果如何:

    结果符合预期。

    在实际的项目中,这样的写法肯定是不符合要求的,一般会做一个封装,新建一个SourceProfile继承自Profile:

    1  public SourceProfile()
    2         {
    3             base.CreateMap<Source, DTOSource>().ForMember(c => c.Desc, q => {
    4                 q.MapFrom(z => z.Content);
    5             });
    6         }

    所有映射关系都可以写在这一个类里,只需要在程序初始化的时候调用一次就可以了:

     1 Mapper.Initialize(x => x.AddProfile<SourceProfile>();  }); 

    博主使用的AutoMapper版本6.1.1.0,因为AutoMapper在6.0版本时移除了Profile中的Configure,所以与6.0版本以下写法有点不同,6.0以下版本写法为:

    1 public class SourceProfile : Profile
    2     {
    3         protected override void Configure()
    4         {
    5             CreateMap<Source, DTOSource>().ForMember(c => c.Desc, q => {
    6                 q.MapFrom(z => z.Content);
    7             });
    8         }
    9     }

    继承Profile重写其Configure即可,调用方式与上述没有太大差别。 Mapper.Initialize中可添加一个或多个Profile。

    在MVC项目的应用中,可以将Mapper.Initialize封装到一个类里;

     public static class AutoMapperForMvc
        {
            public  static void Register()
            {
                Mapper.Initialize(x => {
                    x.AddProfile<SourceProfile>();
                });
            }
    
        }

     进而在MVC的Global中进一次性注册:

     1 public class MvcApplication : System.Web.HttpApplication
     2     {
     3         protected void Application_Start()
     4         {
     5             AreaRegistration.RegisterAllAreas();
     6             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
     7             RouteConfig.RegisterRoutes(RouteTable.Routes);
     8             BundleConfig.RegisterBundles(BundleTable.Bundles);
     9             //注册
    10             AutoMapperForMvc.Register();
    11         }
    12     }

     更多有趣的东西可以查看官方网站

  • 相关阅读:
    Elementary Methods in Number Theory Exercise 1.2.25
    Elementary Methods in Number Theory Exercise 1.2.14
    图解欧几里德算法
    图解欧几里德算法
    Elementary Methods in Number Theory Exercise 1.2.14
    Android中的长度单位详解(dp、sp、px、in、pt、mm)
    分享下多年积累的对JAVA程序员成长之路的总结
    android异常之都是deamon惹的祸The connection to adb is down, and a severe error has occured.
    TomatoCartv1.1.8.2部署时报错
    JavaScript浏览器对象之二Document对象
  • 原文地址:https://www.cnblogs.com/lvlinlv/p/7344916.html
Copyright © 2011-2022 走看看