網(wǎng)站首頁 編程語言 正文
1.什么是AutoMapper?
AutoMapper是一個對象-對象映射器。對象-對象映射通過將一種類型的輸入對象轉換為另一種類型的輸出對象來工作。使AutoMapper變得有趣的是,它提供了一些有趣的約定,免去用戶不需要了解如何將類型A映射為類型B。只要類型B遵循AutoMapper既定的約定,就需要幾乎零配置來映射兩個類型。映射代碼雖然比較無聊,但是AutoMapper為我們提供簡單的類型配置以及簡單的映射測試,而映射可以在應用程序中的許多地方發(fā)生,但主要發(fā)生在層之間的邊界中,比如,UI /域層之間或服務/域層之間。一層的關注點通常與另一層的關注點沖突,因此對象-對象映射導致分離的模型,其中每一層的關注點僅會影響該層中的類型。
2.如何在Core上面使用AutoMapper組件?
先在Startup.ConfigureServices注入AutoMapper組件服務,然后在Startup.Configure上獲取AutoMapper服務配置擴展類創(chuàng)建對象-對象映射關系,為了好統(tǒng)一管理代碼,可以新建一個AutoMapperExtension靜態(tài)類,把以下代碼封裝一下:
public static class AutoMapperExtension { ////// 新增自動映射服務 /// /// ///public static IServiceCollection AddAutoMapper(this IServiceCollection services) { #region 方案一 //注冊AutoMapper配置擴展類服務 services.TryAddSingleton (); //注冊AutoMapper配置擴展類到AutoMapper配置服務去 services.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService (); var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); mapperConfiguration.AssertConfigurationIsValid(); return mapperConfiguration; }); //注入IMapper接口DI服務 services.TryAddSingleton(serviceProvider => { var mapperConfiguration = serviceProvider.GetRequiredService (); return mapperConfiguration.CreateMapper(); }); return services; #endregion } /// /// 使用自動映射配置擴展類 /// /// ///public static IMapperConfigurationExpression UseAutoMapper(this IApplicationBuilder applicationBuilder) { //獲取已注冊服務AutoMapper配置擴展類 return applicationBuilder.ApplicationServices.GetRequiredService (); } } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ...... //添加自動映射組件DI服務 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 (); expression.CreateMap(); }
因為IMapper接口已經(jīng)在ConfigureServices方法注入DI服務了,所以無需再重新注入,只需要直接使用IMapper調用其方法就可以:
public class BlogsController : Controller { private IMapper _iMapper { get; } public BlogsController(IMapper iMapper) { _iMapper = iMapper; } // GET: Blogs public async TaskIndex() { //對象-對象數(shù)據(jù)傳輸 var dto = _iMapper.Map (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() { new Address() {City = "istanbul", Country = "turkey", Id = 5, Street = "istiklal cad."}, new Address() {City = "izmir", Country = "turkey", Id = 6, Street = "konak"} }, Addresses = new List() { 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è)務越來越龐大,需創(chuàng)建對應業(yè)務對象也會越來越多,如果面對這樣的業(yè)務場景難道要在Configure方法里面創(chuàng)建越來越多的映射關系嗎?例:
var expression = app.UseAutoMapper(); expression.CreateMap(); expression.CreateMap(); expression.CreateMap(); expression.CreateMap (); ......
很顯然這樣子是不可行的,這樣會導致后續(xù)代碼越來越多,難以維護。那么現(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ù)傳輸對象)與對應數(shù)據(jù)源對象是傳輸關系,方便在Configure里面自動注冊創(chuàng)建映射關系,例:
//聲明源對象,目標對象 [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 ListWorkAddresses { get; set; } public string AddressCity { get; set; } }
然后創(chuàng)建一個自動注入AutoInjectFactory工廠類,檢測運行中的程序集是否有AutoInjectAttribute屬性聲明,如果有則插入一個類型數(shù)據(jù)集中返回,目的是把所有聲明需要映射DTO對象跟數(shù)據(jù)源對象自動創(chuàng)建映射關系:
public class AutoInjectFactory { public List<(Type, Type)> AddAssemblys { get { var assemblys =new List() { Assembly.GetExecutingAssembly() }; List<(Type, Type)> ConvertList = new List<(Type, Type)>(); foreach (var assembly in assemblys) { var atributes = assembly.GetTypes() .Where(_type => _type.GetCustomAttribute () != null) .Select(_type => _type.GetCustomAttribute ()); foreach (var atribute in atributes) { ConvertList.Add((atribute.SourceType, atribute.TargetType)); } } return ConvertList; } } }
在第2小節(jié)AutoMapperExtension靜態(tài)類的AddAutoMapper方法內修改如下代碼:
#region 方案二 //注入AutoMapper配置擴展類服務 services.TryAddSingleton(); //注入自動注入工廠類服務 services.TryAddSingleton (); //注入AutoMapper配置擴展類到AutoMapper配置服務去 services.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService (); //通過自動注入工廠類獲取聲明數(shù)據(jù)源對象與DTO對象自動創(chuàng)建映射關系 var factory = serviceProvider.GetRequiredService (); foreach (var (sourceType, targetType) in factory.AddAssemblys) { mapperConfigurationExpression.CreateMap(sourceType, targetType); } var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); mapperConfiguration.AssertConfigurationIsValid(); return mapperConfiguration; }); //注入IMapper接口DI服務 services.TryAddSingleton(serviceProvider => { var mapperConfiguration = serviceProvider.GetRequiredService (); return mapperConfiguration.CreateMapper(); }); return services; #endregion
再新增一個使用自動注入工廠類服務靜態(tài)方法:
////// 使用自動注入工廠類 /// /// public static void UseAutoInject(this IApplicationBuilder applicationBuilder) { applicationBuilder.ApplicationServices.GetRequiredService(); }
然后在Startup.ConfigureServices注入AutoMapper組件服務,然后在Startup.Configure上調用UseAutoInject靜態(tài)方法,具體代碼如下:
app.UseAutoInject();
運行效果:
原文鏈接:https://www.cnblogs.com/wzk153/p/12487297.html
相關推薦
- 2022-03-20 .NET+Sqlite支持加密的操作方法_實用技巧
- 2022-04-27 python進階之協(xié)程你了解嗎_python
- 2022-04-12 push到碼云上報錯 ! [rejected] master -> m
- 2023-06-21 C++析構函數(shù)內部工作機制詳解_C 語言
- 2021-12-02 Centos8搭建配置nis域服務詳細步驟_Linux
- 2022-03-28 用python實現(xiàn)一個文件搜索工具_python
- 2023-03-25 Python應用之bin文件的制作_python
- 2022-11-03 淺析C++淺拷貝與深拷貝的聯(lián)系和區(qū)別_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支