zoukankan      html  css  js  c++  java
  • .net core 3.1 WebAPi 使用 AutoMapper 9.0、10.0

    AutoMapper 可以很方便完成数据对象之间的转换。

    Dto -> Entity

    Entity -> ViewModel

    Step 1:通过 NuGet 安装 AutoMapper 的包。

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="AutoMapper" Version="9.0.0" />
        <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
      </ItemGroup>
    
    
    </Project>
    Project.csproj

    准备两个类 User 和 Department

        public class User
        {
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public int Age { get; set; }
    
            public string Remark { get; set; }
    
            public int DepartmentId { get; set; }
    
            public Department DepartmentInfo { get; set; }
        }
    User
        public class Department
        {
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public string Remark { get; set; }
        }
    Department

    创建 User 的 Dto 和 ViewModel

        public class UserDto
        {
            public int Id { get; set; }
    
            public string Name { get; set; }
        }
    UserDto
        public class UserViewModel
        {
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public int Age { get; set; }
    
            public string Remark { get; set; }
    
            public int DepartmentId { get; set; }
    
            public string DepartmentName { get; set; }
        }
    UserViewModel

    Step 2:配置好对象之间的转换。

    创建类 UserMapper 继承抽象类 Profile

        public class UserMapper : Profile
        {
            public UserMapper()
            {
                CreateMap<UserDto, User>();
                CreateMap<User, UserViewModel>()
                    .BeforeMap((u, v) => u.Remark = "Good")
                    .ForMember(v => v.DepartmentId, u => u.MapFrom(user => user.DepartmentId))
                    .ForMember(v => v.DepartmentName, u => u.MapFrom(user => user.DepartmentInfo.Name))
                    .AfterMap((u, v) => u.Age++);
            }
        }
    UserMapper

    Profile 里面实现了两个接口

    Step 3:注册服务

    在 Startup.cs 的 ConfigureServices 方法中注册。

            public void ConfigureServices(IServiceCollection services)
            {
                // ...
                services.AddAutoMapper(typeof(UserMapper));
                // ...
            }    
    ConfigureServices

    Step 4使用

    创建 api 控制器

    声明 private readonly IMapper _mapper;

        [Route("api/[controller]/[action]")]
        [ApiController]
        public class UserController : ControllerBase
        {
            private readonly IMapper _mapper;
    
            public UserController(IMapper mapper)
            {
                _mapper = mapper;
            }
    
            [ActionName("dto")]
            [HttpGet]
            public IActionResult DtoToEntity()
            {
                var userDto = new UserDto() { Id = 1, Name = "Bill" };
                var userEntity = _mapper.Map<UserDto, User>(userDto);
    
                JsonResult result = new JsonResult(userEntity);
                return result;
            }
    
            [ActionName("vo")]
            [HttpGet]
            public IActionResult EntityToViewModel()
            {
                var department = new Department() { Id = 101, Name = "Market" };
                var user = new User() { Id = 1, Name = "Bill", Age = 25, DepartmentId = 101, DepartmentInfo = department };
                var viewModel = _mapper.Map<User, UserViewModel>(user);
    
                JsonResult result = new JsonResult(viewModel);
                return result;
            }
    
        }
    UserController

    结果:

    Dto -> Entity

    Entity -> ViewModel

    Step 5:自动化注册

    如果每添加一个 Mapper 都需要修改 StartUp 类来完成注册,不是什么好方式。

    自动化注册才是更好的(主要还是方便摸鱼)。

    为了实现自动化注册,需要找到项目中的所有 Mapper 对象,要给 Mapper 打上一个标记。

    添加接口类 IProfile

        public interface IProfile
        {
            
        }
    IProfile

    在所有的 Mapper 类里面,实现这个接口。

        public class UserMapper : Profile, IProfile
        {
            public UserMapper()
            {
                CreateMap<UserDto, User>();
                CreateMap<User, UserViewModel>()
                    .BeforeMap((u, v) => u.Remark = "Good")
                    .ForMember(v => v.DepartmentId, u => u.MapFrom(user => user.DepartmentId))
                    .ForMember(v => v.DepartmentName, u => u.MapFrom(user => user.DepartmentInfo.Name))
                    .AfterMap((u, v) => u.Age++);
            }
        }
    UserMapper

    再通过查找所有实现了 IProfile 接口的类,就可以找到所有的 Mapper 对象。

    ( Profile 是 AutoMapper 组件里的接口,必须自定义项目中的唯一标记。)

    创建 MapperRegister 类,实现获取所有的 Mapper 对象。

        public class MapperRegister
        {
            /// <summary>
            /// 通过反射自动化注册
            /// </summary>
            /// <returns></returns>
            public static Type[] MapType()
            {
    
                Assembly ass = Assembly.GetAssembly(typeof(IProfile));
                Type[] types = ass.GetTypes();
    
                List<Type> allList = new List<Type>();
    
                foreach (Type item in types)
                {
                    if (item.IsInterface) continue;//判断是否是接口
                    Type[] ins = item.GetInterfaces();
                    foreach (Type ty in ins)
                    {
                        if (ty == typeof(IProfile))
                        {
                            allList.Add(item);
                        }
                    }
                }
    
                Type[] alltypes = allList.ToArray();
                return alltypes;
            }
    
    
        }
    MapperRegister

    修改 StrartUp 类,调整注册方式。

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
    
                //services.AddAutoMapper(typeof(UserMapper));
                //自动化注册
                services.AddAutoMapper(MapperRegister.MapType());
    
            }
    Startup

    这样就可以每次添加 Mapper 类的时候,只需要添加 IProfile 标记,就可以自动注册了。

    自动化注册方式二

    在很多常见的项目中,同一个项目的Mapper文件都是放在同一个文件夹内。命名都以 Mapper 结尾。

    然后在 Startup.cs 里面

                services.AddAutoMapper(
                    Assembly.Load("Leaf.Application").GetTypes()
                        .Where(t => t.FullName.EndsWith("Mapper"))
                        .ToArray()
                );    
    Assembly.Load() 里面传的是当前项目的名称,或者类库的名称。获取当前项目下的所有类文件。
    通过 Lamda 表达式 Where 找到所有以 Mapper 结尾的文件。
    这样就可以自动注册项目内的所有 Mapper 文件了。
     
    摸鱼又更进了一步。
     
    AutoMapper 配合强类型字段的 ORM 特别好用。比如 EF 。
    入参控制好 Add 的 Dto。
    返回参数 控制好 ViewModel。
    这些文件都可以从数据库 Entity 对象里面复制,不需要手写字段。
    无论多长的字段,都可以通过 Ctrl + C 和 Ctrl + V 来创建对应的 Dto 和 ViewModel 。
    再通过 AutoMapper 的转换。
    做 CURD 接口的时候,不需要写任何 Entity 里已存在的字段。
    然后就可以愉快地上班摸鱼了。
  • 相关阅读:
    img标签为什么可以设置宽高
    高度和宽度的操作
    自增自减运算符
    读取标签内容:innerHTML和innerText的区别 text()和html()的区别
    js中的常用方法
    js中style,currentStyle和getComputedStyle的区别以及获取css操作方法(考虑兼容性和局限性)
    IE盒模型与W3C盒模型区别
    css四种定位方式及其区别
    css隐藏元素的方法何区别
    Hibernate之HQL
  • 原文地址:https://www.cnblogs.com/miaowacao/p/12757275.html
Copyright © 2011-2022 走看看