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