65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 .NET Core API 2.1 的 Automapper

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (10投票s)

2018 年 8 月 12 日

CPOL

3分钟阅读

viewsIcon

50541

downloadIcon

424

本文帮助你开始使用 automapper 并使用一些常用的功能。

引言

AutoMapper 是一种对象到对象的映射,用于轻松地映射不同的对象。 Automapper 最常见的场景之一是尝试将实际对象转换为 DTO 对象。

为了给你一个更好的例子,请考虑以下代码

var Department = GetDepartmentDetails();

DepartmentDetailsDTO obj = new DepartmentDetailsDTO()
{
   obj.Name = Department.Name,
   obj.Id = Department.Id,
   ...
   ...
   //So on . . 
}

想象一下,仅仅为了忽略主对象的一些属性而浪费了多少行代码。 因此,AutoMapper 派上用场,将上面的代码块替换为单行!

在本文中,我们将了解如何在你的项目中设置 Automapper 并使用其一些最受欢迎的功能。 我将展示在 .NET ASP Core 2.1 API 项目中。

背景

由于我们将把 mapper 对象注入到我们的控制器中,因此需要对 API 和依赖注入有一个概念。 最好对 LINQ 有一些基本的了解。

初始设置

首先,让我们创建一个新的 .NET ASP core

Auto_Mapper

接下来,让我们为 Automapper 添加 NuGet 包。 在这里,我们将使用名为AutoMapper.Extensions.Microsoft.DependencyInjection的依赖注入包,如下图所示

Auto_Mapper1

现在 AutoMapper 已经安装好了,我们必须配置startup.cs类,让它知道我们将要注入 automapper。

这是一个简单的单行代码,如下所示,在 ConfigureServices 方法内

//Startup.cs
public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
   services.AddAutoMapper(); // Adding automapper
}

映射配置文件

我们必须将映射配置文件添加到我们的项目中,以告知 Automapper 正确的映射对象方式。

映射配置文件类总是扩展一个 Profile 类。 当程序第一次运行时,Automapper 会找到从 Profile 类继承的类,并加载映射配置。

Automapper 自动映射来自源和目标的同名属性。

让我们创建一个名为Mappings的新文件夹,并向其中添加一个新的映射类,并将其命名为SimpleMappings.cs

namespace AutoMapper.Mappings
{
    public class SimpleMappings : Profile
    {

    }
}

现在是时候添加 DTO 文件夹和 Classes 文件夹了,我们将用适当的类填充它们

//Department.cs
namespace AutoMapper.Classes
{
    public class Department
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Owner { get; set; }
        public string SecretProperty { get; set; } // You dont want to display this
    }
}

这是 DTO 类

//DepartmentDTO.cs
namespace AutoMapper.DTO
{
    public class DepartmentDTO
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Owner { get; set; }
    }
}

完成这些后,让我们回到并修改我们的 MappingProfiles.cs

//MappingProfiles.cs
namespace AutoMapper.Mappings
{
    public class MappingProfiles : Profile
    {
        public MappingProfiles()
        {
            CreateMap<Department, DepartmentDTO>().ReverseMap();
        }
    }
}

请注意,指定 ReverseMap() 允许我们以两种方式进行映射。

最后,是时候添加一个新的控制器了,让我们将其命名为 MappingController

//MappingController
namespace AutoMapper.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class MappingController : Controller
    {
        private readonly IMapper _mapper;
        private readonly Department sampleDepartment;

        public MappingController(IMapper mapper)
        {
            _mapper = mapper; //injected automapper

            //Initializing department object assume from a database
            sampleDepartment = new Department()
            {
                Name = "department1",
                Id = 1,
                Owner = "ABC",
                SecretProperty = "Very secret property"
            };
        }

        [HttpGet]
        public ActionResult<DepartmentDTO> Get()
        {
            return _mapper.Map<DepartmentDTO>(sampleDepartment);
        }
    }
}

这是从 postman 调用到 localhost:<port>/api/mapping 获得的结果

Auto_Mapper2

我们的秘密属性未显示,这意味着我们的 automapper 工作正常。

更深入

在上面的示例中,它是一个简单的单对单映射,但 automapper 也用于对象展平或从展平的对象创建复杂对象。

例如,让我们考虑一个 PersonpersonDTO 对象,如下所示,Person 对象具有一个 Address 属性,该属性是 Address 对象的一种类型。 在这里,我们将从复杂对象创建一个展平的对象。

//Person.cs//Person.cs
namespace AutoMapper.Classes
{
    public class Person
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; }
        public Address Address { get; set; }
    }
}

Address.cs

//Address.cs
namespace AutoMapper.Classes
{
    public class Address
    {
        public string HouseNumber { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
    }
}

PersonDTO.cs 将仅包含 Address 对象的 city 属性。

//PersonDTO.cs
namespace AutoMapper.DTO
{
    public class PersonDTO
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string City { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; } 
    }
}

现在,我们必须回到映射 profile 类,并明确告诉 automapper 从 Addresscity 属性映射 city 属性。 这可以通过 ForMember 来完成,如下面的更新的 MappingProfiles.cs 所示。

//MappingProfiles.cs
namespace AutoMapper.Mappings
{
    public class MappingProfiles : Profile
    {
        public MappingProfiles()
        {
            CreateMap<Department, DepartmentDTO>().ReverseMap();

            //Complex to Flattened
            CreateMap<Person, PersonDTO>()
                .ForMember(dest => dest.City,
                    opts => opts.MapFrom(
                        src => src.Address.City
                    )).ReverseMap();
        }
    }
}

这是完整的 MappingController

namespace AutoMapper.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class MappingController : Controller
    {
        private readonly IMapper _mapper;
        private readonly Department sampleDepartment;
        private readonly Person samplePerson;

        public MappingController(IMapper mapper)
        {
            _mapper = mapper; //injected automapper

            //Initializing department object assume from a database
            sampleDepartment = new Department()
            {
                Name = "department1",
                Id = 1,
                Owner = "ABC",
                SecretProperty = "Very secret property"
            };

            //Initializing person object assume from a database
            samplePerson = new Person()
            {
                Firstname = "John",
                Lastname = "Doe",
                Age = 25,
                Sex = "Male",
                Address = new Address()
                {
                    City = "New York City",
                    HouseNumber = "10",
                    State = "NY",
                    ZipCode = "99999"
                }
            };
        }

        [HttpGet]
        public ActionResult<DepartmentDTO> Get()
        {
            return _mapper.Map<DepartmentDTO>(sampleDepartment);
        }

        [HttpGet]
        [Route("person")]
        public ActionResult<PersonDTO> GetPerson()
        {
            return _mapper.Map<PersonDTO>(samplePerson);
        }
    }
}

最后,这是 postman 上的输出

Auto_Mapper3

最终的 DTO 对象显示了 city。 我们的映射配置有效!

© . All rights reserved.