MAPSTER 是用于 .NET 应用程序的高性能对象到对象映射器。它是一个库,它提供了一种将一种对象类型转换为另一种对象类型的方法,当您想要在应用程序中的层之间转换数据时,例如从数据访问层到业务逻辑层,或从业务逻辑层到表示层,这特别有用。
Mapster的主要优势:
Mapster的设计在速度和内存方面都很高效。我们可以在仅使用 1/3 内存的情况下获得 4 倍的性能提升。
映射器工具之间的性能和内存比较 — 图片来源:这里
在 ASP.NET Core 应用程序中,您可能希望将 Mapster 配置为服务,以便可以在整个应用程序中注入和使用它。我们现在将看到如何设置它。
使用 NuGet 包管理器控制台安装包。
Install-Package Mapster
Install-Package Mapster.DependencyInjection
我们将使用 Mapster 创建一个复杂的映射场景,该对象包含各种属性类型,包括集合和嵌套对象。然后,我们将它映射到 .ProductProductDto
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime ReleaseDate { get; set; }
public List<string> Tags { get; set; }
public List<Review> Reviews { get; set; }
public decimal Price { get; set; }
}
// Product will have multiple Reviews
public class Review
{
public string ReviewerName { get; set; }
public string Content { get; set; }
}
public class ProductDto
{
public int Id { get; set; }
public string Name { get; set; }
// as a formatted string
public string ReleaseDate { get; set; }
public List<string> Tags { get; set; }
public List<ReviewDto> Reviews { get; set; }
public decimal Price { get; set; }
}
public class ReviewDto
{
public string ReviewerName { get; set; }
public string Content { get; set; }
}
在单独的类或方法中定义映射。这样可以使您的配置井井有条且易于管理。配置映射以处理复杂类型,包括列表和嵌套对象。
public static class MapsterConfig
{
public static void Configure()
{
// Configure Product to ProductDto mapping
TypeAdapterConfig<Product, ProductDto>.NewConfig()
.Map(dest => dest.Id, src => src.Id)
.Map(dest => dest.Name, src => src.Name)
.Map(dest => dest.ReleaseDate, src => src.ReleaseDate.ToString("yyyy-MM-dd"))
// direct list mapping
.Map(dest => dest.Tags, src => src.Tags)
// nested objects mapping
.Map(dest => dest.Reviews, src => src.Reviews.Adapt\<List\<ReviewDto>>())
.Map(dest => dest.Price, src => src.Price);
// Configure Review to ReviewDto mapping
TypeAdapterConfig<Review, ReviewDto>.NewConfig()
.Map(dest => dest.ReviewerName, src => src.ReviewerName)
.Map(dest => dest.Content, src => src.Content);
// Any other mappings
}
}
在您的或程序注册文件(取决于您使用的 .NET 版本)中,将 Mapster 和映射配置注册到服务集合。Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddControllers();
// Register Mapster
services.AddMapster();
// Configure Mapster
MapsterConfig.Configure();
}
// Configure method...
}
您可以将 Mapster 提供的接口注入到您的控制器或服务中,并使用它来执行映射。在此设置中,Mapster 与 .NET 依赖项注入系统集成,提供了一种干净且可维护的方式来管理对象到对象的映射。IMapper
public class ProductsController : ControllerBase
{
private readonly IMapper _mapper;
// assuming you have a repository that has GetProductAsync method.
private readonly IProductRepository _repository;
public ProductsController(IMapper mapper, IProductRepository productRepository)
{
_mapper = mapper;
_repository = productRepository;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetProduct(int id)
{
var product = await _repository.GetProductAsync(id);
var productDto = _mapper.Map<ProductDto>(product);
return Ok(productDto);
}
}
var product = new Product
{
// ... initialize with data ...
};
var productDto = product.Adapt<ProductDto>();
[TestClass]
public class ProductsControllerTests
{
private IMapper _mapper;
private Mock<IProductRepository> _mockRepository;
private ProductsController _controller;
[TestInitialize]
public void Initialize()
{
// Initialize and configure Mapster mapper
var config = new TypeAdapterConfig();
MapsterConfig.Configure(config);
_mapper = new Mapper(config);
_mockRepository = new Mock<IProductRepository>();
_controller = new ProductsController(_mapper, _mockRepository.Object);
}
}
在此设置中,是对映射配置方法的调用,以确保映射器的配置与应用程序中的设置方式一致。MapsterConfig.Configure(config)
[TestMethod]
public async Task GetProduct_ReturnsProductDto()
{
// Arrange
var productId = 1;
var product = new Product {
Id = productId,
Name = "Mapster"
/* other properties */
};
_mockRepository.Setup(repo => repo.GetProductAsync(productId))
.ReturnsAsync(product);
// Act
var result = await _controller.GetProduct(productId);
// Assert
var okResult = result as OkObjectResult;
Assert.IsNotNull(okResult);
Assert.AreEqual(StatusCodes.Status200OK, okResult.StatusCode);
var resultProductDto = okResult.Value as ProductDto;
Assert.IsNotNull(resultProductDto);
// You can add more assertions based on your properties
Assert.AreEqual(product.Id, resultProductDto.Id);
//assert other properties
}
通过使用实际的映射器,您的测试将涵盖映射配置,从而提供更集成的测试场景,确保控制器逻辑和映射配置都按预期工作。
Mapster 和 AutoMapper 都是用于对象到对象映射的优秀库。它们之间的选择通常归结为特定的项目需求、性能考虑以及个人或团队偏好。
Mapster 通常因其性能和简单性而受到称赞,尤其是在更复杂的映射场景中,而 AutoMapper 以其成熟度和广泛的社区支持而闻名。