.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 里已存在的字段。
然后就可以愉快地上班摸魚了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM