AutoMapper升级为9.0之后,优化了(简化了)很多使用方法,特别是结合Core系统本身的一些改进,造成了曾经的9.0 以前版本不一样的地方。现做一个总结,代码再某个角度上讲还可以进行优化,欢迎大佬斧正。
环境
vs2019
.Net Core 3.0
AutoMapper 9.0
项目 .Net Core WebApi
*step 0: 本文从Core自带的DI方式来注册使用AutoMapper(目前9.0已经停止了静态api注册,官方推荐注入方式使用)
step 1:首先还是需要直接Nutget两个包:
准备两个数据类
public class User
{
public string Name{get; set;}
}
public class UserDto
{
public string Name{get; set;}
}
step 2 : profile配置
Using AutoMapper;
...
public class UserProfile:Profile
{
public UserProfile()
{
CreateMap<UserDto, User>();
CreateMap<User, UserDto>();
}
}
step 3:入口配置
在startup.cs的
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(typeof(Userprofile));
}
参考官网说明
按照官网说明可以配置继承profile类或者程序集的集合,也就是可以写成(这是比9.0之前更直观的地方,也比之前更方便的扩展)
eg:
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(typeof(Aprofile),typeof(Bprofile),typeof(Cprofile),...);
}
step 4:使用(使用起来也比以前简洁方便)
public class UserService
{
private IMapper mapper{get;set;}
public UserService(IMapper _mapper)
{
this.mapper=_mapper;
}
public UserDto Get()
{
User u=new User(){ Name="金虎大王"};
UserDto dto=mapper.Map<User,UserDto>(User);
return dto;
}
//集合
public List<UserDto> GetList()
{
User u1=new User(){Name="金虎大王"};
User u2=new User(){Name="银虎大王"};
List<User> UserList=new List<User>();
UserList.Add(u1);
UserList.Add(u2);
List<UserDto> dtoList=mapper.Map<List<User>, List<UserDto>>(Userlist);
return dtoList;
}
}
//////////////////////////////
改造
////////////////////////////
因为配置的变化,网上通用的Register和Helper都发生了变化,以下重写这些通用方式
1⃣️通用注册:
Register为了方便扩展,不需要再去service里添加每一个Type
1.先创建一个Iprofile 接口
public interface IProfile
{
}
2.profile配置类继承这个接口
Using AutoMapper;
...
public class UserProfile:Profile,IProfile
{
public UserProfile()
{
CreateMap<UserDto, User>();
CreateMap<User, UserDto>();
}
}
3.创建一个MapperRegister类
public static class MapperRegister
{
public static Type[] MapType()
{
var allIem = Assembly
.GetEntryAssembly()
.GetReferencedAssemblies()
.Select(Assembly.Load)
.SelectMany(y => y.DefinedTypes)
.Where(type =>
typeof(IProfile).GetTypeInfo().IsAssignableFrom(type.AsType()));
List<Type> allList = new List<Type>();
foreach (var typeinfo in allIem)
{
var type = typeinfo.AsType();
allList.Add(type);
}
Type[] alltypes = allList.ToArray();
return alltypes;
}
}
4.更改 StartUp.cs->AddAutoMapper
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(MapperRegister.MapType);
}
所以继承IProfile的配置类都会被自动注册到AutoMapper里
2⃣️通用的方法:AutoMapperHelper
此处AutoMapperHelper有两个意义,一,不需要在每个调用mapper方法的类里再去调用IMapper,由Helper 统一调用一次。二,映射实现的写法更易读(二处的意义现在不太大,9.0之前的Helper方法可以节约三行代码,但9.0更新之后,现在原生的mapper也只需要一行代码)
public static class AutoMapperHelper
{
private static IServiceProvider ServiceProvider;
public static void UseStateAutoMapper(this IApplicationBuilder applicationBuilder)
{
ServiceProvider = applicationBuilder.ApplicationServices;
}
public static TDestination Map<TDestination>(object source)
{
var mapper = ServiceProvider.GetRequiredService<IMapper>();
return mapper.Map<TDestination>(source);
}
public static TDestination Map<TSource, TDestination>(TSource source)
{
var mapper = ServiceProvider.GetRequiredService<IMapper>();
return mapper.Map<TSource, TDestination>(source);
}
public static TDestination MapTo<TSource, TDestination>(this TSource source)
{
var mapper = ServiceProvider.GetRequiredService<IMapper>();
return mapper.Map<TSource, TDestination>(source);
}
public static TDestination MapTo<TDestination>(this object source)
{
var mapper = ServiceProvider.GetRequiredService<IMapper>();
return mapper.Map<TDestination>(source);
}
public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
{
var mapper = ServiceProvider.GetRequiredService<IMapper>();
return mapper.Map<List<TDestination>>(source);
}
public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
{
var mapper = ServiceProvider.GetRequiredService<IMapper>();
return mapper.Map<List<TDestination>>(source);
}
}
在 Startup.cs 配置一下
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
....
app.UseStateAutoMapper();
}
使用:
public class UserService
{
public UserService()
{
}
public UserDto Get()
{
...
UserDto dto=User.MapTo<UserDto>();
return dto;
}
//集合
public List<UserDto> GetList()
{
...
List<UserDto> dtoList=Userlist.MapToList<UserDto>();
return dtoList;
}
}
///////////////
9.0的主要变化
静态API已被删除
AutoMapper不再自动创建映射
其余的9.0的配置,诸如自定义的映射方法等都没有发生变化
详见官网AutoMapper