自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何在 ASP.NET Core 中寫出更干凈的 Controller

開發(fā) 前端
你可以遵循一些最佳實(shí)踐來寫出更干凈的 Controller,一般我們稱這種方法寫出來的 Controller 為瘦Controller,瘦 Controller 的好處在于擁有更少的代碼,更加單一的職責(zé),也便于閱讀和維護(hù),而且隨著時間的推移也容易做 Controller 的多版本。

 [[374901]]

本文轉(zhuǎn)載自微信公眾號「 碼農(nóng)讀書」,作者 碼農(nóng)讀書。轉(zhuǎn)載本文請聯(lián)系 碼農(nóng)讀書公眾號。

你可以遵循一些最佳實(shí)踐來寫出更干凈的 Controller,一般我們稱這種方法寫出來的 Controller 為瘦Controller,瘦 Controller 的好處在于擁有更少的代碼,更加單一的職責(zé),也便于閱讀和維護(hù),而且隨著時間的推移也容易做 Controller 的多版本。

這篇文章我們一起討論那些讓 Controler 變胖變臃腫的一些壞味道,并且一起探索讓 Controller 變瘦的手段,雖然我的一些在 Controller 上的最佳實(shí)踐可能不是專業(yè)的,但我每一步都提供相關(guān)源代碼來進(jìn)行優(yōu)化,接下來的章節(jié)中,我們會討論什么是 胖Controller,什么是 壞味道,什么是 瘦Controller,它能帶給我們什么福利?并且如何讓 Controller 變瘦,變簡單,利測試,易維護(hù)。

從 Controller 中移除數(shù)據(jù)層代碼

當(dāng)在寫 Controller 的時候,你應(yīng)該遵守 單一職責(zé),也就意味著你的 Controller 只需做一件事情,換句話說,只有一個因素或者唯一一個因素能讓你修改 Controller 中的代碼,如果有點(diǎn)懵的話,考慮下面的代碼片段,它將 數(shù)據(jù)訪問代碼 糅進(jìn)了 Controller 。

  1. public class AuthorController : Controller 
  2.     private AuthorContext dataContext = new AuthorContext(); 
  3.     public ActionResult Index(int authorId) 
  4.     { 
  5.         var authors = dataContext.Authors 
  6.             .OrderByDescending(x=>x.JoiningDate) 
  7.             .Where(x=>x.AuthorId == authorId) 
  8.             .ToList(); 
  9.         return View(authors); 
  10.     } 
  11.     //Other action methods 

請注意上面的代碼在 Action 中使用了 dataContext 從數(shù)據(jù)庫讀取數(shù)據(jù),這就違反了單一職責(zé)原則,并直接導(dǎo)致了 Controller 的臃腫。

假如后續(xù)你需要修改 數(shù)據(jù)訪問層 代碼,可能基于更好的性能或者你能想到的原因,這時候只能被迫在 Controller 中修改,舉個例子吧:假如你想把上面的 EF 改成 Dapper 去訪問底層的 Database,更好的做法應(yīng)該是單獨(dú)拎出來一個 repository 類來操控 數(shù)據(jù)訪問 相關(guān)的代碼,下面是更新后的 AuthorController。

  1. public class AuthorController : Controller 
  2.     private AuthorRepository authorRepository = new AuthorRepository(); 
  3.     public ActionResult Index(int authorId) 
  4.     { 
  5.         var authors = authorRepository.GetAuthor(authorId); 
  6.         return View(authors); 
  7.     } 
  8.     //Other action methods 

現(xiàn)在 AuthorController 看起來是不是精簡多了,上面的代碼是不是就是最佳實(shí)踐呢?不完全是,為什么這么說呢?上面這種寫法導(dǎo)致 Controller 變成了 數(shù)據(jù)訪問組件,取出數(shù)據(jù)后必然少不了一些業(yè)務(wù)邏輯處理,這就讓 Controller 違反了 單一職責(zé),對吧,更通用的做法應(yīng)該是將 數(shù)據(jù)訪問邏輯 封裝在一個 service 層,下面是優(yōu)化之后的 AuthorController 類。

  1. public class AuthorController : Controller 
  2.     private AuthorService authorService = new AuthorService(); 
  3.     public ActionResult Index(int authorId) 
  4.     { 
  5.         var authors = authorService.GetAuthor(authorId); 
  6.         return View(authors); 
  7.     } 
  8.     //Other action methods 

再看一下 AuthorService 類,可以看到它利用了 AuthorRepository 去做 CURD 操作。

  1. public class AuthorService 
  2.     private AuthorRepository authorRepository = new AuthorRepository(); 
  3.     public Author GetAuthor (int authorId) 
  4.     { 
  5.         return authorRepository.GetAuthor(authorId); 
  6.     } 
  7.     //Other methods 

避免寫大量代碼做對象之間映射

在 DDD 開發(fā)中,經(jīng)常會存在 DTO 和 Domain 對象,在數(shù)據(jù) Input 和 Output 的過程中會存在這兩個對象之間的 mapping,按照普通的寫法大概就是這樣的。

  1. public IActionResult GetAuthor(int authorId) 
  2.     var author = authorService.GetAuthor(authorId); 
  3.     var authorDTO = new AuthorDTO(); 
  4.     authorDTO.AuthorId = author.AuthorId; 
  5.     authorDTO.FirstName = author.FirstName; 
  6.     authorDTO.LastName = author.LastName; 
  7.     authorDTO.JoiningDate = author.JoiningDate; 
  8.     //Other code 
  9.    ...... 

可以看到,這種一一映射的寫法讓 Controller 即時膨脹,同時也讓 Controller 增加了額外的功能,那如何把這種 模板式 代碼規(guī)避掉呢?可以使用專業(yè)的 對象映射框架 AutoMapper 去解決,下面的代碼展示了如何做 AutoMapper 的配置。

  1. public class AutoMapping 
  2.     public static void Initialize() 
  3.     { 
  4.         Mapper.Initialize(cfg => 
  5.         { 
  6.             cfg.CreateMap<Author, AuthorDTO>(); 
  7.             //Other code             
  8.         }); 
  9.     } 

接下來可以在 Global.asax 中調(diào)用 Initialize() 初始化,如下代碼所示:

  1. protected void Application_Start() 
  2.     AutoMapping.Initialize();          

最后,可以將 mapping 邏輯放在 service 層中,請注意下面的代碼是如何使用 AutoMapper 實(shí)現(xiàn)兩個不兼容對象之間的映射。

  1. public class AuthorService 
  2.     private AuthorRepository authorRepository = new AuthorRepository(); 
  3.     public AuthorDTO GetAuthor (int authorId) 
  4.     { 
  5.         var author = authorRepository.GetAuthor(authorId); 
  6.         return Mapper.Map<AuthorDTO>(author); 
  7.     } 
  8.     //Other methods 

避免在 Controller 中寫業(yè)務(wù)邏輯

盡量避免在 Controller 中寫 業(yè)務(wù)邏輯 或者 驗證邏輯, Controller 中應(yīng)該僅僅是接收一個請求,然后被下一個 action 執(zhí)行,別無其它,回到剛才的問題,這兩種邏輯該怎么處理呢?

  • 業(yè)務(wù)邏輯

這些邏輯可以封裝 XXXService 類中,比如之前創(chuàng)建的 AuthorService。

  • 驗證邏輯

這些邏輯可以用 AOP 的操作手法,比如將其塞入到 Request Pipeline 中處理。

使用依賴注入而不是硬組合

推薦在 Controller 中使用依賴注入的方式來實(shí)現(xiàn)對象之間的管理,依賴注入是 控制反轉(zhuǎn) 的一個子集,它通過外部注入對象之間的依賴從而解決內(nèi)部對象之間的依賴,很拗口是吧!

一旦你用了依賴注入方式,就不需要關(guān)心對象是怎么實(shí)例化的,怎么初始化的,下面的代碼展示了如何在 AuthorController 下的構(gòu)造函數(shù)中實(shí)現(xiàn) IAuthorService 對象的注入。

  1. public class AuthorController : Controller 
  2.     private IAuthorService authorService = new AuthorService(); 
  3.     public AuthorController(IAuthorService authorService) 
  4.     { 
  5.        this.authorService = authorService; 
  6.     } 
  7.    // Action methods 

使用 action filer 消除 Controller 中的重復(fù)代碼

可以利用 action filter 在 Request pipeline 這個管道的某些點(diǎn)上安插一些你的自定義代碼,舉個例子,可以使用 ActionFilter 在 Action 的執(zhí)行前后安插一些自定義代碼,而不是將這些業(yè)務(wù)邏輯放到 Controller 中,讓 Controller 不必要的膨脹,下面的代碼展示了如何去實(shí)現(xiàn)。

  1. [ValidateModelState] 
  2. [HttpPost] 
  3. public ActionResult Create(AuthorRequest request) 
  4.     AuthorService authorService = new AuthorService(); 
  5.     authorService.Save(request); 
  6.     return RedirectToAction("Home"); 

總的來說,如果一個 Controller 被賦予了幾個職責(zé),那么只要是其中任何一個職責(zé)的原因,你都必須對 Controller 進(jìn)行修改,總的來說,一定要堅守 單一原則。

譯文鏈接:https://www.infoworld.com/article/3404472/how-to-write-efficient-controllers-in-aspnet-core.html

 

責(zé)任編輯:武曉燕 來源: 碼農(nóng)讀書
相關(guān)推薦

2021-11-01 14:52:38

ElasticSear索引SQL

2021-03-17 09:45:31

LazyCacheWindows

2021-02-02 16:19:08

Serilog日志框架

2021-02-06 21:40:13

SignalR通訊TypeScript

2021-01-15 05:38:28

ASPHttp端口

2021-01-13 07:33:41

API數(shù)據(jù)安全

2021-01-31 22:56:50

FromServiceASP

2021-02-03 13:35:25

ASPweb程序

2021-03-03 22:37:16

MediatR中介者模式

2021-03-10 09:40:43

LamarASP容器

2021-02-28 20:56:37

NCache緩存框架

2021-01-28 22:39:35

LoggerMessa開源框架

2021-01-07 07:39:07

工具接口 Swagger

2021-03-18 07:33:54

PDF DinkToPdfC++

2021-02-07 17:29:04

監(jiān)視文件接口

2021-03-08 07:32:05

Actionweb框架

2021-02-19 06:54:33

配置系統(tǒng)ASP.NET Cor

2021-01-04 05:44:54

框架日志

2009-08-05 11:00:46

獲得RowIndexASP.NET

2022-08-01 08:00:00

開發(fā)工具跟蹤偵聽器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號