ASP.NET?Core使用AutoMapper組件
1.什么是AutoMapper?
AutoMapper是一個對象-對象映射器。對象-對象映射通過將一種類型的輸入對象轉(zhuǎn)換為另一種類型的輸出對象來工作。使AutoMapper變得有趣的是,它提供了一些有趣的約定,免去用戶不需要了解如何將類型A映射為類型B。只要類型B遵循AutoMapper既定的約定,就需要幾乎零配置來映射兩個類型。映射代碼雖然比較無聊,但是AutoMapper為我們提供簡單的類型配置以及簡單的映射測試,而映射可以在應(yīng)用程序中的許多地方發(fā)生,但主要發(fā)生在層之間的邊界中,比如,UI /域?qū)又g或服務(wù)/域?qū)又g。一層的關(guān)注點通常與另一層的關(guān)注點沖突,因此對象-對象映射導(dǎo)致分離的模型,其中每一層的關(guān)注點僅會影響該層中的類型。
2.如何在Core上面使用AutoMapper組件?
先在Startup.ConfigureServices注入AutoMapper組件服務(wù),然后在Startup.Configure上獲取AutoMapper服務(wù)配置擴展類創(chuàng)建對象-對象映射關(guān)系,為了好統(tǒng)一管理代碼,可以新建一個AutoMapperExtension靜態(tài)類,把以下代碼封裝一下:
public static class AutoMapperExtension { /// <summary> /// 新增自動映射服務(wù) /// </summary> /// <param name="service"></param> /// <returns></returns> public static IServiceCollection AddAutoMapper(this IServiceCollection services) { #region 方案一 //注冊AutoMapper配置擴展類服務(wù) services.TryAddSingleton<MapperConfigurationExpression>(); //注冊AutoMapper配置擴展類到AutoMapper配置服務(wù)去 services.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService<MapperConfigurationExpression>(); var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); mapperConfiguration.AssertConfigurationIsValid(); return mapperConfiguration; }); //注入IMapper接口DI服務(wù) services.TryAddSingleton(serviceProvider => { var mapperConfiguration = serviceProvider.GetRequiredService<MapperConfiguration>(); return mapperConfiguration.CreateMapper(); }); return services; #endregion } /// <summary> /// 使用自動映射配置擴展類 /// </summary> /// <param name="applicationBuilder"></param> /// <returns></returns> public static IMapperConfigurationExpression UseAutoMapper(this IApplicationBuilder applicationBuilder) { //獲取已注冊服務(wù)AutoMapper配置擴展類 return applicationBuilder.ApplicationServices.GetRequiredService<MapperConfigurationExpression>(); } } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ...... //添加自動映射組件DI服務(wù) services.AddAutoMapper(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ...... //注冊組件之后,創(chuàng)建映射對象 var expression = app.UseAutoMapper(); expression.CreateMap<Customer, CustomerDto>(); expression.CreateMap<Address, AddressDto>(); }
因為IMapper接口已經(jīng)在ConfigureServices方法注入DI服務(wù)了,所以無需再重新注入,只需要直接使用IMapper調(diào)用其方法就可以:
public class BlogsController : Controller { private IMapper _iMapper { get; } public BlogsController(IMapper iMapper) { _iMapper = iMapper; } // GET: Blogs public async Task<IActionResult> Index() { //對象-對象數(shù)據(jù)傳輸 var dto = _iMapper.Map<CustomerDto>(CustomerInitialize()); ...... } //手動賦值客戶對象數(shù)據(jù) private Customer CustomerInitialize() { var _customer = new Customer() { Id = 1, Name = "Eduardo Najera", Credit = 234.7m, Address = new Address() { City = "istanbul", Country = "turkey", Id = 1, Street = "istiklal cad." }, HomeAddress = new Address() { City = "istanbul", Country = "turkey", Id = 2, Street = "istiklal cad." }, WorkAddresses = new List<Address>() { new Address() {City = "istanbul", Country = "turkey", Id = 5, Street = "istiklal cad."}, new Address() {City = "izmir", Country = "turkey", Id = 6, Street = "konak"} }, Addresses = new List<Address>() { new Address() {City = "istanbul", Country = "turkey", Id = 3, Street = "istiklal cad."}, new Address() {City = "izmir", Country = "turkey", Id = 4, Street = "konak"} }.ToArray() }; return _customer; } }
運行效果:
3.如果更加靈活使用AutoMapper組件?
相信在第二章節(jié)時候,相信大家都會發(fā)現(xiàn)一個問題,如果生產(chǎn)場景業(yè)務(wù)越來越龐大,需創(chuàng)建對應(yīng)業(yè)務(wù)對象也會越來越多,如果面對這樣的業(yè)務(wù)場景難道要在Configure方法里面創(chuàng)建越來越多的映射關(guān)系嗎?例:
var expression = app.UseAutoMapper(); expression.CreateMap<A, ADto>(); expression.CreateMap<B, BDto>(); expression.CreateMap<C, CDto>(); expression.CreateMap<D, DDto>(); ......
很顯然這樣子是不可行的,這樣會導(dǎo)致后續(xù)代碼越來越多,難以維護(hù)。那么現(xiàn)在讓我們來解決這個問題。首先新建一個自動注入屬性的AutoInjectAttribute密封類,具體代碼如下:
public sealed class AutoInjectAttribute : Attribute { public Type SourceType { get; } public Type TargetType { get; } public AutoInjectAttribute(Type sourceType, Type targetType) { SourceType = sourceType; TargetType = targetType; } }
新增這個AutoInjectAttribute密封類,目的是聲明每個DTO對象(數(shù)據(jù)傳輸對象)與對應(yīng)數(shù)據(jù)源對象是傳輸關(guān)系,方便在Configure里面自動注冊創(chuàng)建映射關(guān)系,例:
//聲明源對象,目標(biāo)對象 [AutoInject(sourceType: typeof(Customer),targetType:typeof(CustomerDto))] public class CustomerDto { public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } public AddressDto HomeAddress { get; set; } public AddressDto[] Addresses { get; set; } public List<AddressDto> WorkAddresses { get; set; } public string AddressCity { get; set; } }
然后創(chuàng)建一個自動注入AutoInjectFactory工廠類,檢測運行中的程序集是否有AutoInjectAttribute屬性聲明,如果有則插入一個類型數(shù)據(jù)集中返回,目的是把所有聲明需要映射DTO對象跟數(shù)據(jù)源對象自動創(chuàng)建映射關(guān)系:
public class AutoInjectFactory { public List<(Type, Type)> AddAssemblys { get { var assemblys =new List<Assembly>() { Assembly.GetExecutingAssembly() }; List<(Type, Type)> ConvertList = new List<(Type, Type)>(); foreach (var assembly in assemblys) { var atributes = assembly.GetTypes() .Where(_type => _type.GetCustomAttribute<AutoInjectAttribute>() != null) .Select(_type => _type.GetCustomAttribute<AutoInjectAttribute>()); foreach (var atribute in atributes) { ConvertList.Add((atribute.SourceType, atribute.TargetType)); } } return ConvertList; } } }
在第2小節(jié)AutoMapperExtension靜態(tài)類的AddAutoMapper方法內(nèi)修改如下代碼:
#region 方案二 //注入AutoMapper配置擴展類服務(wù) services.TryAddSingleton<MapperConfigurationExpression>(); //注入自動注入工廠類服務(wù) services.TryAddSingleton<AutoInjectFactory>(); //注入AutoMapper配置擴展類到AutoMapper配置服務(wù)去 services.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService<MapperConfigurationExpression>(); //通過自動注入工廠類獲取聲明數(shù)據(jù)源對象與DTO對象自動創(chuàng)建映射關(guān)系 var factory = serviceProvider.GetRequiredService<AutoInjectFactory>(); foreach (var (sourceType, targetType) in factory.AddAssemblys) { mapperConfigurationExpression.CreateMap(sourceType, targetType); } var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); mapperConfiguration.AssertConfigurationIsValid(); return mapperConfiguration; }); //注入IMapper接口DI服務(wù) services.TryAddSingleton(serviceProvider => { var mapperConfiguration = serviceProvider.GetRequiredService<MapperConfiguration>(); return mapperConfiguration.CreateMapper(); }); return services; #endregion
再新增一個使用自動注入工廠類服務(wù)靜態(tài)方法:
/// <summary> /// 使用自動注入工廠類 /// </summary> /// <param name="applicationBuilder"></param> public static void UseAutoInject(this IApplicationBuilder applicationBuilder) { applicationBuilder.ApplicationServices.GetRequiredService<AutoInjectFactory>(); }
然后在Startup.ConfigureServices注入AutoMapper組件服務(wù),然后在Startup.Configure上調(diào)用UseAutoInject靜態(tài)方法,具體代碼如下:
app.UseAutoInject();
運行效果:
到此這篇關(guān)于ASP.NET Core使用AutoMapper組件的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
一文輕松了解ASP.NET與ASP.NET?Core多環(huán)境配置對比
ASP.NET?Core支持在多個環(huán)境中管理應(yīng)用程序,如開發(fā)(Development),預(yù)演(Staging)和生產(chǎn)(Production),下面這篇文章主要給大家介紹了關(guān)于ASP.NET與ASP.NET?Core多環(huán)境配置對比?的相關(guān)資料,需要的朋友可以參考下2022-04-04.net Core連接MongoDB數(shù)據(jù)庫的步驟詳解
這篇文章主要給大家介紹了關(guān)于.net Core連接MongoDB數(shù)據(jù)庫步驟的相關(guān)資料,文中將實現(xiàn)的步驟一步步介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02asp.net利用Ajax和Jquery在前臺向后臺傳參數(shù)并返回值的實例
asp.net利用Ajax和Jquery在前臺向后臺傳參數(shù)并返回值的實例,需要的朋友可以參考一下2013-05-05