欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 对象映射使用,项目部署Windows+Linux完整版,

程序员文章站 2022-05-21 17:34:31
今天刚看到老张的哲学博客关于AutoMapper的教程,从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 对象映射使用,项目部署Windows+Linux完整版, 看得我有点晕,我搞不得那个CustomProfile跟AutoMapperProfile是干 ......

今天刚看到老张的哲学博客关于automapper的教程,从壹开始前后端分离【 .net core2.0 +vue2.0 】框架之十三 || dtos 对象映射使用,项目部署windows+linux完整版, 看得我有点晕,我搞不得那个customprofile跟automapperprofile是干什么用的,可能我水平也比较菜,理解能力差点,然后我通过百度后,发现这个确实就是一个很简单的东西。

 

主要分四步

  1. 安装nuget依赖包 automapper(我安装时是8.1版本,这个包在你web层跟放profile类的层上),automapper.extensions.microsoft.dependencyinjection(依赖注入的,主要是用到一个addautomapper方法,这个是安装在web层的),如果你没有分层的话,你也可以只安装个automapper.extensions.microsoft.dependencyinjection就行了,因为这个包本身就依赖automapper包;
  2. 创建继承profile类(这是automapper的配置类)的子类,这个是用来配置实体跟dto的映射的配置;
  3. 在web层的startup.cs的configureservices方法中增加services.addautomapper(),这个方法会获取程序集里所有继承profile类的派生类进行注册并把imapper注入到服务容器里;
  4. 然后就可以在controller或service里通过构造函数注入imapper,然后用mapper.map<>()进行实体与dto的转换了。

注:我在第一次安装nuget包时出现一个比较奇怪的情况,就是我先安装的automapper.extensions.microsoft.dependencyinjection包,然后直接在web层测试怎么用automapper,学会后我想把profile放到service层后,然后在service层上安装automapper包,然后按f6生成解决方案后,发现依赖包就自动消失了,弄了好久次,一按f6,automapper包就自动消失,我一直搞不懂为什么,然后我把整个解决方案里automapper相关的代码跟依赖包都删了,然后再安装个automapper跟automapper.extensions.microsoft.dependencyinjection,就正常了,后面我想重现之前的问题,但发现我怎么装都正常了,这是个很奇怪的问题,我也搞不懂为什么。

以下是我的解决方案目录,第一个红圈是web层,第二个红圈是service层,我把映射的profile放在service层的automapper目录,因为我觉得映射就是service该干的活

从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 对象映射使用,项目部署Windows+Linux完整版,

 

这是实体类sysuser,我放在了entity层

public class sysuser
{
        [key]        
        public int id { get; set; }
       
        public string loginname { get; set; }

        public string name { get; set; }
}

这是sysuser对应的dto类sysuserdto,我放在了dto层,注意那个testname字段,是我等下用来演示用的

public class sysuserdto
{
        public int id { get; set; }
        public string loginname { get; set; }
        public string name { get; set; }
        public string testname { get; set; }
}

 

然后我在service里创建一个文件夹automapper,创建一个mapperprofile.cs类,记得安装automapper包

从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 对象映射使用,项目部署Windows+Linux完整版,

 

mapperprofile.cs,我目前是把所有实体跟dto的映射都写在一个profile类中,就是创建很多个createmap

using automapper;
using system;
using system.collections.generic;
using system.text;
using itsys.entity;
using itsys.dto;

namespace itsys.service.automapper
{
    public class mapperprofile : profile
    {
        public mapperprofile()
        {
            //创建sysuser往sysuserdto转换的映射,reversemap是创建反向映射,不过我发现如果都是同名的属性的话,没加这个reversemap也是能反向映射的
            createmap<sysuser, sysuserdto>().reversemap();
        }
    }
}

 

然后在web层的startup.cs类里的configureservices方法里addautomapper(记得安装automapper.extensions.microsoft.dependencyinjection包),这个方法会自动找到所有继承了profile类的配置类进行映射配置

public iserviceprovider configureservices(iservicecollection services)
{
      services.addautomapper(); 
}

注意这个方法如果像我上面这样写的话,就会获取所有引用的程序集里所有继承了profile类的派生类进行配置,所以我即使profile放在service层里也是能获取到的,当然你也可以传入一个程序集参数,例如这样:addautomapper(assembly.getassembly(typeof(baseservice<>))),或者传入一个类addautomapper(typeof(baseservice<>)),那automapper就只会在程序集或类的程序集范围内查找了。

然后我在sysuserservice类里就可以这样写了,注意红色的代码

using system;
using system.collections.generic;
using system.text;
using itsys.dto;
using itsys.repository.sys;
using itsys.entity;
using automapper;

namespace itsys.service.sys
{
    public class sysuserservice : baseservice<sysuser>
    {
        private imapper _mapper;
        protected sysuserrepository repository;

        public sysuserservice(sysuserrepository repository,imapper mapper) 
        {
            base.baserepository = repository;
            this.repository = repository;
            _mapper = mapper;
        }
        public virtual sysuserdto getbyid(int id)
        {
            var sysuserentity = repository.getbyid(id);
            if (sysuserentity == null)
            {
                throw new exception("没找到数据");
            }
            return _mapper.map<sysuserdto>(sysuserentity);
        }
    }
}

所以automapper使用起来就是这么简单的。

 

对了,关于那个sysuserdto的testname字段,如果我想这个字段等于sysuser的loginname跟name字段相连的字符串,怎么弄的,很简单,在那个mapperprofile类中这么写

using automapper;
using system;
using system.collections.generic;
using system.text;
using itsys.entity;
using itsys.dto;

namespace itsys.service.automapper
{
    public class mapperprofile : profile
    {
        public mapperprofile()
        {
            //创建sysuser往sysuserdto转换的映射,reversemap是创建反向映射,如果都是同名的属性的话,没加这个reversemap也是能反向映射的,不过像以下这个有特殊属性的,就得加reversemap才能正常反向映射
            createmap<sysuser, sysuserdto>()
                .formember(destinationobject => destinationobject.testname, options =>
                {
                    //目标类的testname等于实体类的loginname加上name字段
                    options.mapfrom(sourceobject => sourceobject.loginname + sourceobject.name);
                 })
                .reversemap();
        }
    }
}