日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
如何在ASP.NETCore中寫出更干凈的Controller

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

創(chuàng)新互聯(lián),為您提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)站營(yíng)銷推廣、網(wǎng)站開發(fā)設(shè)計(jì),對(duì)服務(wù)水處理設(shè)備等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)及推廣經(jīng)驗(yàn)。創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司成立于2013年,提供專業(yè)網(wǎng)站制作報(bào)價(jià)服務(wù),我們深知市場(chǎng)的競(jìng)爭(zhēng)激烈,認(rèn)真對(duì)待每位客戶,為客戶提供賞心悅目的作品。 與客戶共同發(fā)展進(jìn)步,是我們永遠(yuǎn)的責(zé)任!

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

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

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

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

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

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

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

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

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

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

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

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

避免寫大量代碼做對(duì)象之間映射

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

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

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

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

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

 
 
 
  1. protected void Application_Start()
  2. {
  3.     AutoMapping.Initialize();         
  4. }

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

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

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

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

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

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

  • 驗(yàn)證邏輯

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

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

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

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

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

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

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

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

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


當(dāng)前名稱:如何在ASP.NETCore中寫出更干凈的Controller
文章地址:http://www.5511xx.com/article/ccichdc.html