首页 > 其他分享 >Add AutoMapper

Add AutoMapper

时间:2022-10-22 18:48:48浏览次数:88  
标签:opt set string 映射 get Add AutoMapper public

(注:本文示例使用的是.NET Core 3.1)

1. 配置 (Configuration)

Reference: https://docs.automapper.org/en/latest/Configuration.html

多种方法配置,这里推荐使用配置文件实例 (Profile Instances)。创建继承自Profile并将配置放入构造函数的类。

1.1 安装NuGet包:

Install-Package AutoMapper -Version 11.0.1

1.2 新建Profile Instance:

// This is the approach starting with version 5
public class MyAppProfile : Profile
{
	public MyAppProfile()
	{
		CreateMap<Source, Destination>();
		// Use CreateMap... Etc.. here 
	}
}

2. 依赖注入 (Dependency Injection)

Reference: https://docs.automapper.org/en/latest/Dependency-injection.html

1)安装NuGet包

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection -Version 11.0.0

2)添加到StartUp的ConfigureServices

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
	
    // Add auto mapper
    services.AddAutoMapper(typeof(MyAppProfile));
    // services.AddAutoMapper(typeof(ProfileTypeFromAssembly));
    // services.AddAutoMapper(typeof(ProfileTypeFromAssembly1), typeof(ProfileTypeFromAssembly2) /*, ...*/);
}

3)将 AutoMapper 注入services / controllers:

public class HomeController : ControllerBase
{
    private readonly IMapper _mapper;

    public HomeController(IMapper mapper)
    {
        _mapper = mapper;
    }
}

3. 重写配置 (Override configuration)

3.1 使用 Ignore()

目标类型有个属性Xxx,跳过 Map 操作。

CreateMap<Source, Destination>()
	.ForMember(d => d.Xxx, opt => opt.Ignore());

3.2 空替换 (Null Substitution)

Reference: https://docs.automapper.org/en/latest/Null-substitution.html

空替换允许您为目标属性提供替代值。这意味着它不会从 null 映射,而是从你提供的值映射。

CreateMap<Source, Destination>()
    .ForMember(d => d.Xxx, opt => opt.NullSubstitute("Other Value"));

3.3 自定义 (MapFrom)

Reference: https://docs.automapper.org/en/latest/Projection.html

CreateMap<Source, Destination>()
	.ForMember(d => d.ValueLength, opt => opt.MapFrom(s => s != null ? s.Value.Length : 0));

3.4 条件映射 (Conditional Mapping)

Reference: https://docs.automapper.org/en/latest/Conditional-mapping.html

AutoMapper 允许将条件添加到在映射该属性之前必须满足的属性。

在下面的映射中,属性 Baz 只有在源对象中大于或等于 0 时才会被映射。

CreateMap<Source, Destination>()
    .ForMember(d => d.Baz, opt => opt.Condition(s => (s.Baz >= 0)));

3.5 前提条件 (Preconditions)

Reference: https://docs.automapper.org/en/latest/Conditional-mapping.html#preconditions

同样,还有一个 PreCondition 方法。不同之处在于它在映射过程中运行得更快,在解析源值之前(想想 MapFrom)。所以先决条件被调用,然后我们决定哪个是映射(解析)的源,然后调用条件,最后分配目标值。

CreateMap<Source, Destination>()
    .ForMember(d => d.Baz, opt => {
        opt.PreCondition(s => (s.Baz >= 0));
        opt.MapFrom(s => {
            // Expensive resolution process that can be avoided with a PreCondition
        });
    });

4. 支持列表和数组映射 (Lists and Arrays)

Reference: https://docs.automapper.org/en/latest/Lists-and-arrays.html

支持的源集合类型包括:

  • IEnumerable
  • IEnumerable
  • ICollection
  • ICollection
  • IList
  • IList
  • List
  • Arrays

5. 支持嵌套映射 Nested Mappings

Reference: https://docs.automapper.org/en/latest/Nested-mappings.html

当映射引擎执行映射时,它可以使用多种方法之一来解析目标成员值。其中一种方法是使用另一种类型映射,其中源成员类型和目标成员类型也在映射配置中进行配置。这使我们不仅可以扁平化我们的源类型,还可以创建复杂的目标类型。例如,我们的源类型可能包含另一个复杂类型:

public class Source
{
	public int Value { get; set; }
	public InnerSource Inner { get; set; }
}

public class InnerSource
{
	public int OtherValue { get; set; }
}
public class Destination
{
	public int Value { get; set; }
	public InnerDestination Inner { get; set; }
}

public class InnerDestination
{
	public int OtherValue { get; set; }
}

在这种情况下,配置类型映射:

CreateMap<Source, Destination>();
CreateMap<InnerSource, InnerDestination>();

【注意】:

  • 配置类型的顺序无关紧要
  • 调用 Map 不需要指定任何内部类型映射,只需要指定用于传入的源值的类型映射

6. 示例:

Class:

public class Student
{
    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Nickname { get; set; }
    public int? Age { get; set; }
    public DateTime UpdatedDate { get; set; }
    public string AddressId { get; set; }
    public virtual Address Address { get; set; }
}

public class Address
{
    public string Id { get; set; }
    public string PostalCode { get; set; }
    public string Block { get; set; }
    public string Street { get; set; }
    public string Floor { get; set; }
    public string Unit { get; set; }
    public string Building { get; set; }
}
public class StudentDto
{
    public string Id { get; set; }
    public string FullName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Nickname { get; set; }
    public int? Age { get; set; }
    public DateTime CreatedDate { get; set; }
    public string PostalCode { get; set; }
    public string AddressStreet { get; set; }
    public AddressDto Address { get; set; }

}

public class AddressDto
{
    public string PostalCode { get; set; }
    public string Block { get; set; }
    public string Street { get; set; }
    public string Floor { get; set; }
    public string Unit { get; set; }
    public string Building { get; set; }
}

Profile:

public class MyAppProfile : Profile
{
    public MyAppProfile()
    {
        CreateMap<Student, StudentDto>()
            .ForMember(d => d.Nickname, opt => opt.NullSubstitute("Anonymous"))
            .ForMember(d => d.FullName, opt => opt.MapFrom(s => s.FirstName + " " + s.LastName))
            .ForMember(d => d.PostalCode, opt => opt.MapFrom(s => s.Address != null ? s.Address.PostalCode : null))
            .ForMember(d => d.Age, opt => opt.Condition(s => s.Age.HasValue && s.Age.Value > 0))
            .ForMember(d => d.AddressStreet, opt =>
            {
                opt.PreCondition(s => s.Address != null);
                opt.MapFrom(s => s.Address.Street);
            });
        CreateMap<StudentDto, Student>()
            .ForMember(d => d.Id, opt => opt.Ignore())
            .ForMember(d => d.AddressId, opt => opt.Ignore())
            .ForMember(d => d.UpdatedDate, opt => opt.MapFrom(s => DateTime.Now));

        CreateMap<Address, AddressDto>();
        CreateMap<AddressDto, Address>()
            .ForMember(d => d.Id, opt => opt.Ignore());
    }
}

Test:

// Create Entity
var entity = _mapper.Map<Student>(dto);
// Update Entity
_mapper.Map(dto, entity);
// Get Dto
var dto = _mapper.Map<StudentDto>(entity);
// Get Dto List
var dtoList = _mapper.Map<List<StudentDto>>(entityList);

标签:opt,set,string,映射,get,Add,AutoMapper,public
From: https://www.cnblogs.com/keirahuy/p/16816912.html

相关文章