<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
AutoMapper是一個物件-物件對映器。物件-物件對映通過將一種型別的輸入物件轉換為另一種型別的輸出物件來工作。使AutoMapper變得有趣的是,它提供了一些有趣的約定,免去使用者不需要了解如何將型別A對映為型別B。只要型別B遵循AutoMapper既定的約定,就需要幾乎零設定來對映兩個型別。對映程式碼雖然比較無聊,但是AutoMapper為我們提供簡單的型別設定以及簡單的對映測試,而對映可以在應用程式中的許多地方發生,但主要發生在層之間的邊界中,比如,UI /域層之間或服務/域層之間。一層的關注點通常與另一層的關注點衝突,因此物件-物件對映導致分離的模型,其中每一層的關注點僅會影響該層中的型別。
先在Startup.ConfigureServices注入AutoMapper元件服務,然後在Startup.Configure上獲取AutoMapper服務設定擴充套件類建立物件-物件對映關係,為了好統一管理程式碼,可以新建一個AutoMapperExtension靜態類,把以下程式碼封裝一下:
public static class AutoMapperExtension { /// <summary> /// 新增自動對映服務 /// </summary> /// <param name="service"></param> /// <returns></returns> public static IServiceCollection AddAutoMapper(this IServiceCollection services) { #region 方案一 //註冊AutoMapper設定擴充套件類服務 services.TryAddSingleton<MapperConfigurationExpression>(); //註冊AutoMapper設定擴充套件類到AutoMapper設定服務去 services.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService<MapperConfigurationExpression>(); var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); mapperConfiguration.AssertConfigurationIsValid(); return mapperConfiguration; }); //注入IMapper介面DI服務 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) { //獲取已註冊服務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服務 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<Customer, CustomerDto>(); expression.CreateMap<Address, AddressDto>(); }
因為IMapper介面已經在ConfigureServices方法注入DI服務了,所以無需再重新注入,只需要直接使用IMapper呼叫其方法就可以:
public class BlogsController : Controller { private IMapper _iMapper { get; } public BlogsController(IMapper iMapper) { _iMapper = iMapper; } // GET: Blogs public async Task<IActionResult> Index() { //物件-物件資料傳輸 var dto = _iMapper.Map<CustomerDto>(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<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; } }
執行效果:
相信在第二章節時候,相信大家都會發現一個問題,如果生產場景業務越來越龐大,需建立對應業務物件也會越來越多,如果面對這樣的業務場景難道要在Configure方法裡面建立越來越多的對映關係嗎?例:
var expression = app.UseAutoMapper(); expression.CreateMap<A, ADto>(); expression.CreateMap<B, BDto>(); expression.CreateMap<C, CDto>(); expression.CreateMap<D, DDto>(); ......
很顯然這樣子是不可行的,這樣會導致後續程式碼越來越多,難以維護。那麼現在讓我們來解決這個問題。首先新建一個自動注入屬性的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 List<AddressDto> WorkAddresses { get; set; } public string AddressCity { get; set; } }
然後建立一個自動注入AutoInjectFactory工廠類,檢測執行中的程式集是否有AutoInjectAttribute屬性宣告,如果有則插入一個型別資料集中返回,目的是把所有宣告需要對映DTO物件跟資料來源物件自動建立對映關係:
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小節AutoMapperExtension靜態類的AddAutoMapper方法內修改如下程式碼:
#region 方案二 //注入AutoMapper設定擴充套件類服務 services.TryAddSingleton<MapperConfigurationExpression>(); //注入自動注入工廠類服務 services.TryAddSingleton<AutoInjectFactory>(); //注入AutoMapper設定擴充套件類到AutoMapper設定服務去 services.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService<MapperConfigurationExpression>(); //通過自動注入工廠類獲取宣告資料來源物件與DTO物件自動建立對映關係 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服務 services.TryAddSingleton(serviceProvider => { var mapperConfiguration = serviceProvider.GetRequiredService<MapperConfiguration>(); return mapperConfiguration.CreateMapper(); }); return services; #endregion
再新增一個使用自動注入工廠類服務靜態方法:
/// <summary> /// 使用自動注入工廠類 /// </summary> /// <param name="applicationBuilder"></param> public static void UseAutoInject(this IApplicationBuilder applicationBuilder) { applicationBuilder.ApplicationServices.GetRequiredService<AutoInjectFactory>(); }
然後在Startup.ConfigureServices注入AutoMapper元件服務,然後在Startup.Configure上呼叫UseAutoInject靜態方法,具體程式碼如下:
app.UseAutoInject();
執行效果:
到此這篇關於ASP.NET Core使用AutoMapper元件的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45