上一篇文章(http://www.javashuo.com/article/p-thfwubrk-dy.html)集成了定時任務處理框架Hangfire,完成了一個簡單的定時任務處理解決方案。html
本篇緊接着來玩一下AutoMapper,AutoMapper能夠很方便的搞定咱們對象到對象之間的映射關係處理,同時abp也幫咱們是現實了IObjectMapper
接口,先根據官方文檔:https://docs.abp.io/zh-Hans/abp/latest/Object-To-Object-Mapping ,將AutoMapper添加依賴到項目中。git
在.Application
層模塊類中添加AbpAutoMapperModule
模塊依賴。github
//MeowvBlogApplicationModule.cs using Meowv.Blog.Application.Caching; using Volo.Abp.AutoMapper; using Volo.Abp.Identity; using Volo.Abp.Modularity; namespace Meowv.Blog.Application { [DependsOn( typeof(AbpIdentityApplicationModule), typeof(AbpAutoMapperModule), typeof(MeowvBlogApplicationCachingModule) )] public class MeowvBlogApplicationModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { ... } } }
在本項目中,主要處理的就是實體和DTO以前的映射關係,以以前寫的BlogService.cs
中的增刪改查爲例,將Post.cs
和PostDto.cs
互相映射。跨域
先看GetPostAsync(int id)
這個方法,以前的作法是手動建立對象,而後爲其一個一個的賦值,能夠想象當咱們的字段超級多的時候,都得寫一遍。如今有了AutoMapper,一句代碼就能夠搞定。安全
public async Task<ServiceResult<PostDto>> GetPostAsync(int id) { var result = new ServiceResult<PostDto>(); var post = await _postRepository.GetAsync(id); if (post == null) { result.IsFailed("文章不存在"); return result; } //var dto = new PostDto //{ // Title = post.Title, // Author = post.Author, // Url = post.Url, // Html = post.Html, // Markdown = post.Markdown, // CategoryId = post.CategoryId, // CreationTime = post.CreationTime //}; var dto = ObjectMapper.Map<Post, PostDto>(post); result.IsSuccess(dto); return result; }
ObjectMapper
在ApplicationService
中已經被注入,咱們的繼承了ServiceBase
,能夠直接使用。app
到這裏還沒完,其中最重要的一步就是定義類與類之間的映射關係,AutoMapper提供了多種定義類之間映射的方法,有關詳細信息請參閱AutoMapper的文檔:https://docs.automapper.org/框架
其中定義一種映射的方法是建立一個Profile 類,在.Application
層添加MeowvBlogAutoMapperProfile.cs
,直接繼承Profile
在構造函數中定義便可。async
//MeowvBlogAutoMapperProfile.cs using AutoMapper; using Meowv.Blog.Application.Contracts.Blog; using Meowv.Blog.Domain.Blog; namespace Meowv.Blog.Application { public class MeowvBlogAutoMapperProfile : Profile { public MeowvBlogAutoMapperProfile() { CreateMap<Post, PostDto>(); CreateMap<PostDto, Post>().ForMember(x => x.Id, opt => opt.Ignore()); } } }
定義兩個規則,第一個:從Post
映射到PostDto
,由於PostDto
全部屬性在Post
中都是存在的,因此直接CreateMap<>
便可;第二個:從PostDto
映射到Post
,由於Post
中存在Id屬性,而在PostDto
中是沒有的,因此能夠使用ForMember(...)
來忽略掉Id屬性。ide
定義好映射規則後,在模塊類中添加使用。函數
//MeowvBlogApplicationModule.cs ... public override void ConfigureServices(ServiceConfigurationContext context) { Configure<AbpAutoMapperOptions>(options => { options.AddMaps<MeowvBlogApplicationModule>(validate: true); options.AddProfile<MeowvBlogAutoMapperProfile>(validate: true); }); } ...
使用一樣的方式修改一下InsertPostAsync(PostDto dto)
方法的代碼。
public async Task<ServiceResult<string>> InsertPostAsync(PostDto dto) { var result = new ServiceResult<string>(); //var entity = new Post //{ // Title = dto.Title, // Author = dto.Author, // Url = dto.Url, // Html = dto.Html, // Markdown = dto.Markdown, // CategoryId = dto.CategoryId, // CreationTime = dto.CreationTime //}; var entity = ObjectMapper.Map<PostDto, Post>(dto); var post = await _postRepository.InsertAsync(entity); if (post == null) { result.IsFailed("添加失敗"); return result; } result.IsSuccess("添加成功"); return result; }
解放了雙手,代碼也變少了,真香,去測試一下用了對象映射後的接口是否好使。
能夠看到,結果也是能夠出來的,後續都將按照上面的方法大量用到對象映射。
順便介紹.HttpApi.Hosting
層幾個配置屬性。
路由規則配置,默認Swagger中的路由是大寫的,若是我想轉成小寫能夠使用如下配置代碼,都寫在模塊類MeowvBlogHttpApiHostingModule.cs
中。
public override void ConfigureServices(ServiceConfigurationContext context) { ... context.Services.AddRouting(options => { // 設置URL爲小寫 options.LowercaseUrls = true; // 在生成的URL後面添加斜槓 options.AppendTrailingSlash = true; }); ... }
使用HSTS的中間件,該中間件添加了嚴格傳輸安全頭。
public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... app.UseHsts(); ... }
直接使用默認的跨域配置。
public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... app.UseCors(); ... }
HTTP請求轉HTTPS。
public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... app.UseHttpsRedirection(); ... }
轉發將標頭代理到當前請求,配合 Nginx 使用,獲取用戶真實IP。
public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... pp.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); ... }
本篇介紹瞭如何使用AutoMapper,搞定對象到對象間的映射,篇幅簡短,內容比較簡單,你學會了嗎?😁😁😁