zoukankan      html  css  js  c++  java
  • Asp.net Core 2.2关于AutoMapper更初级的入门教程

    今天刚看到老张的哲学博客关于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该干的活

    这是实体类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包

    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();
            }
        }
    }
  • 相关阅读:
    Linux 线程间通信方式+进程通信方式 总结
    使用opencv第三方库的makefile文件示例
    rplidar SDK 二次开发---之获取目标信息(0.1)
    #include "Target_orientation.h"
    opencv —— 调用摄像头采集图像 VideoCapture capture(0);
    cmake 支持-lpthread
    ROS下sensor_msgs::ImagePtr到sensor_msgs::Image之间的转换
    JAVA 校验身份证号码工具类(支持15位和18位)
    python面向对象游戏练习:好人坏人手枪手榴弹
    python 私有属性的作用
  • 原文地址:https://www.cnblogs.com/caijt/p/10781277.html
Copyright © 2011-2022 走看看