简介:本文详细解析AutoMapper的使用方法,涵盖基础配置、高级映射技巧、性能优化及最佳实践,助力开发者高效实现对象间属性映射。
AutoMapper 是一个基于.NET平台的对象-对象映射库,通过约定优于配置的原则,将源对象属性自动映射到目标对象,消除手动赋值代码。其核心价值体现在三个方面:
典型应用场景包括:DTO与实体类的转换、视图模型构建、API响应数据封装等。据统计,使用AutoMapper可使映射代码量减少70%以上。
通过NuGet安装核心包:
Install-Package AutoMapperInstall-Package AutoMapper.Extensions.Microsoft.DependencyInjection
在ASP.NET Core中配置服务:
// Startup.cs 或 Program.csservices.AddAutoMapper(typeof(Program).Assembly);// 或指定多个程序集// services.AddAutoMapper(Assembly.GetExecutingAssembly(), Assembly.Load("OtherAssembly"));
// 方式1:Profile基类public class MappingProfile : Profile{public MappingProfile(){CreateMap<Source, Destination>().ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}")).IgnoreAllPropertiesWithAnInaccessibleSetter();}}// 方式2:静态配置(适用于简单场景)var config = new MapperConfiguration(cfg => {cfg.CreateMap<Order, OrderDto>();});
// 通过依赖注入获取IMapperpublic class OrderService{private readonly IMapper _mapper;public OrderService(IMapper mapper){_mapper = mapper;}public OrderDto GetOrder(int id){var order = _repository.GetById(id);return _mapper.Map<OrderDto>(order);}}// 或直接使用Mapper实例var config = new MapperConfiguration(cfg => cfg.CreateMap<Product, ProductViewModel>());var mapper = config.CreateMapper();var viewModel = mapper.Map<ProductViewModel>(product);
// 嵌套对象映射CreateMap<Customer, CustomerDto>().ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.ShippingAddress));// 集合映射CreateMap<List<Product>, List<ProductSummary>>();// 或使用泛型CreateMap<IEnumerable<Order>, IEnumerable<OrderLite>>();
public class DateFormatterResolver : IValueResolver<Source, Destination, string>{public string Resolve(Source source, Destination destination, string destMember, ResolutionContext context){return source.CreateDate.ToString("yyyy-MM-dd");}}// 在Profile中注册CreateMap<Source, Destination>().ForMember(dest => dest.FormattedDate, opt => opt.MapFrom<DateFormatterResolver>());
CreateMap<Employee, EmployeeDto>().ForMember(dest => dest.Bonus, opt => opt.Condition(src => src.PerformanceRating > 8));
CreateMap<Order, OrderDto>().ReverseMap();// 或定制反向映射CreateMap<OrderDto, Order>().ForMember(dest => dest.Id, opt => opt.Ignore());
// 应用程序启动时编译var config = new MapperConfiguration(cfg => {cfg.AddProfile<MappingProfile>();});config.AssertConfigurationIsValid(); // 验证配置// 使用编译后的映射var mapper = config.CreateMapper();
AutoMapper默认使用ConcurrentDictionary缓存映射计划,在以下场景建议手动管理:
// 映射集合时避免循环引用var orders = repository.GetAll();var dtos = mapper.Map<List<OrderDto>>(orders);// 大数据量分批处理const int batchSize = 1000;var total = sourceCollection.Count;for (int i = 0; i < total; i += batchSize){var batch = sourceCollection.Skip(i).Take(batchSize);var batchResult = mapper.Map<List<Destination>>(batch);// 处理批次结果}
// 启动时验证所有映射配置var config = new MapperConfiguration(cfg => {cfg.AddProfile<ApplicationProfile>();});try{config.AssertConfigurationIsValid();}catch (AutoMapperConfigurationException ex){// 处理配置错误}
ForMember配置或使用Ignore().MaxDepth(1)或使用DTO剪枝
[Test]public void Should_Correctly_Map_Customer_To_Dto(){var config = new MapperConfiguration(cfg => cfg.AddProfile<CustomerProfile>());var mapper = config.CreateMapper();var source = new Customer { Id = 1, Name = "Test" };var result = mapper.Map<CustomerDto>(source);Assert.AreEqual(source.Id, result.Id);Assert.AreEqual(source.Name, result.Name);}
// Startup.cspublic void ConfigureServices(IServiceCollection services){services.AddAutoMapper(typeof(Startup));// 其他服务配置...}
public class AutoMapperInitializer{public static MapperConfiguration Initialize(){var profiles = GetAllProfiles(); // 实现自定义Profile加载逻辑return new MapperConfiguration(cfg => {foreach (var profile in profiles){cfg.AddProfile(profile);}});}}
| AutoMapper版本 | .NET支持范围 | 推荐使用场景 |
|---|---|---|
| 10.x | .NET Standard 2.0 | 传统ASP.NET Core 3.1项目 |
| 11.x | .NET 6/7 | 现代跨平台应用 |
| 12.x (预览) | .NET 8 | 最新技术栈 |
注意:升级到新版本时,需检查
ReverseMap和AfterMap等API的变更,建议通过单元测试验证关键映射逻辑。
安装示例:
Install-Package AutoMapper.Collection
// 1. 定义模型public class Product {public int Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }}public class ProductDto {public int Id { get; set; }public string DisplayName { get; set; }public string FormattedPrice { get; set; }}// 2. 创建映射配置public class ProductProfile : Profile{public ProductProfile(){CreateMap<Product, ProductDto>().ForMember(dest => dest.DisplayName, opt => opt.MapFrom(src => src.Name.ToUpper())).ForMember(dest => dest.FormattedPrice, opt => opt.MapFrom(src => $"${src.Price:F2}"));}}// 3. 在服务中使用public class ProductService{private readonly IMapper _mapper;public ProductService(IMapper mapper) => _mapper = mapper;public IEnumerable<ProductDto> GetProducts(){var products = _repository.GetAll(); // 假设从数据库获取return _mapper.Map<IEnumerable<ProductDto>>(products);}}
通过系统掌握上述内容,开发者可以构建出高效、可维护的对象映射解决方案。建议结合具体项目需求,从简单映射开始逐步引入高级特性,同时建立完善的单元测试体系确保映射正确性。