網站首頁 編程語言 正文
1.什么是AutoMapper?
AutoMapper是一個對象-對象映射器。對象-對象映射通過將一種類型的輸入對象轉換為另一種類型的輸出對象來工作。使AutoMapper變得有趣的是,它提供了一些有趣的約定,免去用戶不需要了解如何將類型A映射為類型B。只要類型B遵循AutoMapper既定的約定,就需要幾乎零配置來映射兩個類型。映射代碼雖然比較無聊,但是AutoMapper為我們提供簡單的類型配置以及簡單的映射測試,而映射可以在應用程序中的許多地方發生,但主要發生在層之間的邊界中,比如,UI /域層之間或服務/域層之間。一層的關注點通常與另一層的關注點沖突,因此對象-對象映射導致分離的模型,其中每一層的關注點僅會影響該層中的類型。
2.如何在Core上面使用AutoMapper組件?
先在Startup.ConfigureServices注入AutoMapper組件服務,然后在Startup.Configure上獲取AutoMapper服務配置擴展類創建對象-對象映射關系,為了好統一管理代碼,可以新建一個AutoMapperExtension靜態類,把以下代碼封裝一下:
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) { ...... //注冊組件之后,創建映射對象 var expression = app.UseAutoMapper(); expression.CreateMap (); expression.CreateMap(); }
因為IMapper接口已經在ConfigureServices方法注入DI服務了,所以無需再重新注入,只需要直接使用IMapper調用其方法就可以:
public class BlogsController : Controller { private IMapper _iMapper { get; } public BlogsController(IMapper iMapper) { _iMapper = iMapper; } // GET: Blogs public async TaskIndex() { //對象-對象數據傳輸 var dto = _iMapper.Map (CustomerInitialize()); ...... } //手動賦值客戶對象數據 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組件?
相信在第二章節時候,相信大家都會發現一個問題,如果生產場景業務越來越龐大,需創建對應業務對象也會越來越多,如果面對這樣的業務場景難道要在Configure方法里面創建越來越多的映射關系嗎?例:
var expression = app.UseAutoMapper(); expression.CreateMap(); expression.CreateMap(); expression.CreateMap(); expression.CreateMap (); ......
很顯然這樣子是不可行的,這樣會導致后續代碼越來越多,難以維護。那么現在讓我們來解決這個問題。首先新建一個自動注入屬性的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對象(數據傳輸對象)與對應數據源對象是傳輸關系,方便在Configure里面自動注冊創建映射關系,例:
//聲明源對象,目標對象 [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; } }
然后創建一個自動注入AutoInjectFactory工廠類,檢測運行中的程序集是否有AutoInjectAttribute屬性聲明,如果有則插入一個類型數據集中返回,目的是把所有聲明需要映射DTO對象跟數據源對象自動創建映射關系:
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小節AutoMapperExtension靜態類的AddAutoMapper方法內修改如下代碼:
#region 方案二 //注入AutoMapper配置擴展類服務 services.TryAddSingleton(); //注入自動注入工廠類服務 services.TryAddSingleton (); //注入AutoMapper配置擴展類到AutoMapper配置服務去 services.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService (); //通過自動注入工廠類獲取聲明數據源對象與DTO對象自動創建映射關系 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
再新增一個使用自動注入工廠類服務靜態方法:
////// 使用自動注入工廠類 /// /// public static void UseAutoInject(this IApplicationBuilder applicationBuilder) { applicationBuilder.ApplicationServices.GetRequiredService(); }
然后在Startup.ConfigureServices注入AutoMapper組件服務,然后在Startup.Configure上調用UseAutoInject靜態方法,具體代碼如下:
app.UseAutoInject();
運行效果:
原文鏈接:https://www.cnblogs.com/wzk153/p/12487297.html
相關推薦
- 2022-11-07 Android內置SQLite的使用詳細介紹_Android
- 2022-07-01 Python自動操作Excel文件的方法詳解_python
- 2022-11-10 使用python的pandas讀取excel文件中的數據詳情_python
- 2022-05-10 thymeleaf跳轉到響應頁面(modelandview 中的view)
- 2022-07-30 C語言強制類型轉換規則實例詳解_C 語言
- 2022-11-14 C#中對集合排序的三種方式_C#教程
- 2021-12-15 C/C++?Qt?數據庫與Chart歷史數據展示_C 語言
- 2022-03-13 C語言實現求最大公約數的三種方法_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支