ibcadmin 发表于 2019-11-8 09:55:21

Dotnet Core中使用AutoMapper

<p>官网:<a href="http://automapper.org/">http://automapper.org/</a></p>
<p><strong>文档:</strong><a href="https://automapper.readthedocs.io/en/latest/index.html" target="_blank">https://automapper.readthedocs.io/en/latest/index.html</a></p>
<p><strong>GitHub:</strong><a href="https://github.com/AutoMapper/AutoMapper/blob/master/docs/index.rst" target="_blank">https://github.com/AutoMapper/AutoMapper/blob/master/docs/index.rst</a></p>
<p><strong>什么是AutoMapper?</strong></p>
<p>  AutoMapper是一个对象-对象映射器。对象-对象映射通过将一种范例的输入对象转换为另一种范例的输出对象来工作。使AutoMapper变得风趣的是,它提供了一些风趣的约定,以免除搞清楚怎样将范例A映射为范例B。只要范例B遵照AutoMapper既定的约定,就须要险些零设置来映射两个范例。</p>
<p><strong>为什么要利用AutoMapper?</strong></p>
<p>  映射代码很无聊。测试映射代码更加无聊。AutoMapper提供了简单的范例设置以及简单的映射测试。真正的标题大概是“为什么利用对象-对象映射?”映射可以在应用步伐中的许多地方发生,但主要发生在层之间的边界中,比方UI /域层或服务/域层之间。一层的关注点通常与另一层的关注点辩论,因此对象-对象映射导致分离的模子,此中每一层的关注点仅会影响该层中的范例。</p>
<p><strong>AutoMapper的利用场景:</strong></p>
<p>  AutoMapper是对象到对象的映射工具。在完成映射规则之后,AutoMapper可以将源对象转换为目的对象。<br />一样平常环境下,表现层与应用层之间是通过DTO(数据传输对象Data Transfer Object)来举行交互的,数据传输对象是没有活动的POCO对象(简单CLR对象Plain Old CLR Object),他的目的是为了对范畴对象举行数据封装,实现层与层之间的数据转达。为何不直接将范畴对象举行数据转达?由于范畴对象更注意范畴,DTO更注意数据。由于“富范畴模子”的特点,如许会直接将范畴对象的活动袒露给表现层。<br />DTO自己不是业务对象,它是根据UI需求举行筹划的。简单来说Model面向业务,我们是通过业务来界说Model的。而DTO是面向UI,通过UI的需求来界说的,通过DTO我们实现了表现层与Model层之间的解耦,表现层不引用Model。如果开辟过程中我们的模子变了,而界面没变,我们只需改Model而不须要去改动表现层。</p>
<p><strong>怎样利用AutoMapper?</strong></p>
<p>  首先,您须要同时利用源范例和目的范例。目的范例的筹划大概会受到其所在层的影响,但是只要成员名称与源范例的成员匹配,AutoMapper的效果最佳。如果您有一个名为“ FirstName”的源成员,它将自动映射到名称为“ FirstName”的目的成员。AutoMapper还支持<ahref="https://automapper.readthedocs.io/en/latest/Flattening.html">Flattening</a>。</p>
<p>  将源映射到目的时,AutoMapper将忽略空引用非常。这是筹划使然。如果您不喜欢这种方法,则可以根据须要将AutoMapper的方法与<ahref="https://automapper.readthedocs.io/en/latest/Custom-value-resolvers.html">自界说值剖析器</a>联合利用。</p>
<p><strong>怎样在Dotnet Core中利用AutoMapper?</strong></p>
<p>首先,要安装依赖包:</p>
<p></p>
<p> </p>
<p> 在Startup.cs中利用Dotnet Core自带的容器举行注入,由于我内里是示例代码,新建的示例Demo也没有去改名字,也都是在同一个定名空间下的,但是在现实项目中是不会出现这种标题的</p>

//添加对AutoMapper的支持
services.AddAutoMapper(Assembly.Load("WebApplication1"), Assembly.Load("WebApplication1"));

<p></p>
<p> 即下图所示的关系:</p>
<p></p>
<p>源范例Model对象,与映射后的DTO范例:</p>

public class UserInfo
{
   public string UserName { get; set; }

   public string UserPwd { get; set; }

   public string GetCreateTime { get; set; }

}


public class UserInfoDTO
{
    public string UserName { get; set; }

    public string UserPwd { get; set; }

    public string Role { get; set; }

    public DateTime CreateTime { get; set; }

    public string TestTime { get; set; }
}

<p><strong>Profile的用法:</strong></p>
<p>  Profile提供了一个定名的映射类,所有继承自Profile类的子类都是一个映射集合。这里我们创建一个UserProfile继承Profile类。</p>
<p>  CreateMap:创建映射规则。</p>
<p>  BeforeMap:在映射之前实行的方法。</p>
<p>  AfterMap:反之,映射之后实行的方法。</p>
<p>  自动化扁平映射:AutoMapper会将类中的属性举行分割,或匹配"Get"开头的方法。</p>
<p>  ForMember:指定映射字段。</p>

public class UserProfile : Profile
{
    //添加你的遗体映射关系
    public UserProfile()
    {
      CreateMap<UserInfo, UserInfoDTO>()
            .BeforeMap((source, dto) =>
            {
                //可以较为正确的控制输出数据格式
                if (string.IsNullOrEmpty(source.GetCreateTime))
                {
                  source.GetCreateTime = Convert.ToDateTime(source.GetCreateTime).ToString("yyyy-MM-dd");
                }
            })
            //指定映射字段。将UserInfo.GetCreateTime映射到UserInfoDTO.TestTime
            .ForMember(dto => dto.TestTime, opt => opt.MapFrom(info => info.GetCreateTime))
            .ForMember(dto => dto.Role, opt => opt.Ignore())
            .ForMember(dto => dto.CreateTime, opt => opt.Ignore());

      CreateMap<StudentInfo, UserInfo>();
    }
}

<p>控制器注入IMapper:</p>

private readonly IMapper _mapper;

public HomeController(IMapper mapper)
{
    _mapper = mapper;
}

<p>单个对象转DTO:</p>

//模拟数据
var user = new UserInfo()
{
    UserName = "bingle",
    UserPwd = "12345"
};
var userDto = _mapper.Map<UserInfoDTO>(user);

<p>集合转Dto集合:</p>

//模拟数据
var userList = new List<UserInfo>
{
    new UserInfo
    {
      UserName="bingle_1",
      UserPwd="1"
    },
    new UserInfo
    {
      UserName="bingle_2",
      UserPwd="2"
    },
    new UserInfo
    {
      UserName="bingle_3",
      UserPwd="3"
    },
    new UserInfo
    {
      UserName="bingle_4",
      UserPwd="4"
    },
    new UserInfo
    {
      UserName="bingle_5",
      UserPwd="5"
    },
    new UserInfo
    {
      UserName="bingle_6",
      UserPwd="6"
    }
};
//对象集合转Dto集合
var usersDtos = _mapper.Map<List<UserInfoDTO>>(userList);

<p>  AutoMapper功能很强盛,在这边先容的只是很少的功能,有爱好的同伴可以去AutoMapper官方文档深入学习。</p>
<p>  如果有小同伴觉得在利用AutoMapper都得在Controller的构造函数中举行注入一遍贫苦的话,AutoMapper也是支持这种映射方式如:Mapper.Map</p>
<p>实例方式:</p>

//模拟数据
var user = new UserInfo()
{
    UserName = "bingle",
    UserPwd = "12345"
};
var config = new MapperConfiguration(cfg => cfg.CreateMap<UserInfo, UserInfoDTO>());
var mapper = config.CreateMapper();

var userDTO = mapper.Map<UserInfoDTO>(user);

<p>参考:<a href="https://blog.csdn.net/weixin_37207795/article/details/81009878">https://blog.csdn.net/weixin_37207795/article/details/81009878</a></p>
页: [1]
查看完整版本: Dotnet Core中使用AutoMapper