AutoMapper 在NetCore8 中实践
AutoMapper注入和创建方式
AutoMapper的创建通常涉及几个关键步骤,这些步骤可以概括为以下几种方式:
- 静态方式
- 实例方式
- 使用Profile类(推荐)
public class DemoMapper: Profile
{
public DemoMapper()
{
CreateMap<sourceA, sourceB>()
.ForMember(dest => dest.A, opt => opt.MapFrom(source => source.B))
.ForMember(dest => dest.C, opt => opt.MapFrom(source => source.D))
.ReverseMap();
}
}
注册方式
services.AddAutoMapper(profileAssembly1, profileAssembly2 /*, ...*/);
/**OR*/
services.AddAutoMapper(typeof(ProfileTypeFromAssembly1), typeof(ProfileTypeFromAssembly2)
/**样例命名空间下导入*/
services.AddAutoMapper(cfg => { cfg.AddMaps("Demo.AutoMapper"); });
/*, ...*/);
使用
Now you can inject AutoMapper at runtime into your services/controllers:
public class EmployeesController {
private readonly IMapper _mapper;
public EmployeesController(IMapper mapper) => _mapper = mapper;
// use _mapper.Map or _mapper.ProjectTo
}
IValueResolver
在处理复杂的映射场景时,有时可能需要自定义逻辑来映射特定的属性。为了支持这种需求,AutoMapper 提供了 IValueResolver 接口,允许你定义自定义的值解析器。
.ForMember(dest => dest.TargetProperty, opt => opt.MapFrom<CustomResolver>());
/**********************/
public class CustomResolver : IValueResolver<Source, Destination, Destination, string>
{
public string Resolve(Source source, Destination destination, Destination destMember, ResolutionContext context)
{
// 这里可以编写自定义的映射逻辑
// 例如,根据源对象的属性计算出一个新的值
return source.SomeProperty + " processed";
}
}
注意点 opt.MapFrom()这么写的前提是CustomResolver必须注入。
这么写不需要提前注入.opt.MapFrom(new CustomResolver())
IValueConverter
alueConverter 是另一个接口,用于在类型映射时执行自定义的转换逻辑。与 IValueResolver 类似,但 IValueConverter 通常用于在源和目标类型之间执行更通用的转换,而不仅仅是基于源和目标对象的特定实例。
IValueConverter 接口允许你定义一个类,该类将处理从一种类型到另一种类型的转换,而不需要依赖于源或目标对象的特定实例。这使得 IValueConverter 在某些场景下比 IValueResolver 更为合适,特别是当转换逻辑不依赖于源或目标对象的当前状态时。
.ForMember(dest => dest.IntProperty, opt => opt.ConvertUsing<CustomConverter>());
/**********************/
public class CustomConverter : IValueConverter<string, int>
{
public int Convert(string source, ResolutionContext context)
{
// 这里可以编写自定义的转换逻辑
// 例如,将字符串解析为整数(但请注意处理可能的异常)
if (int.TryParse(source, out int result))
{
return result;
}
else
{
// 处理转换失败的情况,例如返回默认值或抛出异常
return 0; // 或者你可能想要抛出一个异常
}
}
}
其他
还有数据校验等暂不补充了