當(dāng)前位置:首頁 > IT技術(shù) > Windows編程 > 正文

《ASP.ENT Core 與 RESTful API 開發(fā)實(shí)戰(zhàn)》(第3章)-- 讀書筆記(中)
2021-10-22 16:45:26


第 3 章 ASP.NET Core 核心特性

3.3 依賴注入

通常情況下,應(yīng)用程序由多個(gè)組件構(gòu)成,而組件與組件之間往往存在依賴關(guān)系

當(dāng)我們需要獲取數(shù)據(jù)時(shí),通常的做法是實(shí)例化依賴的類,然后調(diào)用類里面的方法,但是這種依賴方式會(huì)增加調(diào)用方和被調(diào)用方之間的耦合,也會(huì)增加應(yīng)用程序維護(hù)成本及靈活性,同時(shí)增加了單元測試的難度

為了解決這一問題,需要用到依賴倒置原則,高層不直接依賴低層,兩者均依賴抽象

public class Book
{

}

public interface IDataService
{
List<Book> GetAllBooks();
}

public class DataService : IDataService
{
public List<Book> GetAllBooks()
{
return new List<Book>();
}
}

public class DisplayDataService
{
private readonly IDataService _dataService;

public DisplayDataService(IDataService dataService)
{
_dataService = dataService;
}

public void ShowData()
{
var data = _dataService.GetAllBooks();
}
}


接下來,只需要在實(shí)例化 DisplayDataService 的時(shí)候,在構(gòu)造函數(shù)傳入一個(gè) IDataService 接口的具體實(shí)現(xiàn)即可

IDataService dataService = new DataService();
DisplayDataService displayDataService = new DisplayDataService(dataService);


除了構(gòu)造函數(shù)注入之外,還有屬性注入和方法注入

當(dāng)應(yīng)用程序中有多處要用到依賴注入時(shí),就需要一個(gè)專門的類來負(fù)責(zé)管理創(chuàng)建所需要的類并創(chuàng)建所有它可能要用到的依賴,這個(gè)類就是依賴注入容器,也可以稱為控制反轉(zhuǎn)容器,IOC 容器

在 ASP.NET Core 中,所有被放入依賴注入容器的類型或組件被稱為服務(wù)

容器中的服務(wù)有兩種類型:第一種是框架服務(wù),它們是 ASP.NET Core 框架的組成部分;另一種是應(yīng)用服務(wù),所有由用戶放到容器中的服務(wù)都屬于這一類

在 ASP.NET Core 內(nèi)置的依賴注入容器中,服務(wù)的生命周期有如下3種類型:

  • Singleton:容器會(huì)創(chuàng)建并共享服務(wù)的單例,且一直會(huì)存在于應(yīng)用程序的整個(gè)生命周期內(nèi)
  • Transient:每次服務(wù)被請求時(shí),總會(huì)創(chuàng)建新實(shí)例
  • Scoped:在每一次請求時(shí)會(huì)創(chuàng)建服務(wù)的新實(shí)例,并在這個(gè)請求內(nèi)一直共享這個(gè)實(shí)例

3.4 MVC

MVC 是模型、視圖、控制器的縮寫,它是 Web 應(yīng)用程序中一種常見的架構(gòu)模式,最主要的優(yōu)點(diǎn)是實(shí)現(xiàn)了關(guān)注點(diǎn)分離

在 ASP.NET Core MVC 框架中,除了 Controller、Model 和 Action 外,它還包括路由、模型綁定、模型驗(yàn)證和過濾器等功能

路由的主要功能是根據(jù)預(yù)先配置的路由信息對客戶端傳來的請求進(jìn)行路由映射,映射完成后,再將請求傳給對應(yīng)的路由處理器處理

對于 ASP.NET Core MVC,定義路由的方法有以下兩種:

  • 基于約定的路由
  • 特性路由

基于約定的路由需要在 Startup 類中指明,具體來說,應(yīng)該在配置 MVC 中間件時(shí)來設(shè)置路由約定

app.UseMvc(routes =>
{
routes.MapRoute("default",template: "{controller}/{action}");
});


以下約定為 controller 和 action 設(shè)置了默認(rèn)值,參數(shù) id 后面有一個(gè)問號,說明這個(gè)參數(shù)時(shí)可選的,在 URL 中有無此項(xiàng)都可以,注意,一個(gè) URL 模板中只能有一個(gè)可選參數(shù),并且只能放在最后

app.UseMvc(routes =>
{
routes.MapRoute("default",template: "{controller=Home}/{action=Index}/{id?}");
});


指定參數(shù)時(shí),也可以添加約束

app.UseMvc(routes =>
{
routes.MapRoute("default",template: "{controller=Home}/{action=Index}/{id:int}");
});


特性路由只需要在 Controller 類或 Action 方法上添加 [Route] 特性即可

[Route("Home")]
public class HomeController : Controller
{
[Route("Index")]
public IActionResult Index()
{
return View();
}
}


當(dāng) Controller 需要依賴其他服務(wù)時(shí),通常的做法是使用構(gòu)造函數(shù)注入所需要的服務(wù),當(dāng)程序運(yùn)行時(shí),ASP.NET Core 會(huì)在創(chuàng)建 Controller 時(shí)自動(dòng)從其依賴注入的容器中獲取所有依賴的服務(wù),需要注意的是,所注入的服務(wù)必須存在于容器中,否則會(huì)發(fā)生異常

Action 的返回結(jié)果有以下4類:

  • StatusCode
  • ObjectResult
  • 重定向結(jié)果
  • 內(nèi)容結(jié)果

模型綁定:將 HTTP 請求中的數(shù)據(jù)映射到 Action 中參數(shù)的過程

ASP.NET Core MVC 模型綁定特性:

  • [FromHeader]
  • [FromQuery]
  • [FromServices]
  • [FromRoute]
  • [FromForm]
  • [FromBody]

還有兩個(gè)特性用于指明參數(shù)是否必須使用綁定:

  • BindRequiredAttribute
  • BindNeverAttribute

模型驗(yàn)證:指數(shù)據(jù)被使用之前的驗(yàn)證過程,它發(fā)生在模型綁定之后

數(shù)據(jù)注解通常用于驗(yàn)證,只要為類的屬性添加需要的數(shù)據(jù)注解驗(yàn)證特性即可:

  • [Required]
  • [MinLength(10)]
  • [Url]
  • [Range(1,5)]

在 Controller 內(nèi)的 Action 中,要檢查一個(gè)對象是否滿足指定的條件,只要調(diào)用 ModelState.IsVaild 屬性,其中 ModelState 是 ControllerBase 類的屬性

ASP.NET Core MVC 提供兩種創(chuàng)建自定義驗(yàn)證的方法:

  • 創(chuàng)建新特性,并使它繼承自 ValidationAttribute 類
  • 使待驗(yàn)證的 Model 實(shí)現(xiàn) IValidatableObject 接口

過濾器:與中間件很相似,在 ASP.NET Core MVC 中,它們能夠在某些功能的前后執(zhí)行,由此形成一個(gè)管道

ASP.NET Core MVC 提供了以下5種類型的過濾器:

  • Authorization
  • Resource
  • Action
  • Exception
  • Result

當(dāng)要?jiǎng)?chuàng)建過濾器時(shí),應(yīng)該實(shí)現(xiàn) IXXXFilter 或 IAsyncXXXFilter,前者同步,后者異步,實(shí)現(xiàn)一個(gè)即可

在 startup 種注冊過濾器會(huì)使它影響到應(yīng)用中的每個(gè) Action,如果要僅為一個(gè)或少數(shù)幾個(gè) Action 添加過濾器,就得使用特性,ASP.NET Core 為每一種類型的過濾器都定義了相應(yīng)的特性

如果以特性的方式使用包含依賴項(xiàng)的過濾器時(shí),就會(huì)出錯(cuò),因?yàn)樵谧远x特性的構(gòu)造函數(shù)中定義的接口類型的參數(shù)并不是有效的特性參數(shù),此時(shí)需要使用 [ServiceFilter] 特性或者 [TypeFilter] 特性,并設(shè)置它們的 Type 屬性為自定義過濾器類型

[ServiceFilter] 特性與 [TypeFilter] 特性的區(qū)別是前者會(huì)從容器中獲取過濾器實(shí)例,而后者不會(huì),它使用 ObjectFactory 對指定的過濾器類型進(jìn)行實(shí)例化,如果使用前者,需要在 Startup 類的 ConfigureServices 方法中將該過濾器添加到容器中

《ASP.ENT Core 與 RESTful API 開發(fā)實(shí)戰(zhàn)》(第3章)-- 讀書筆記(中)_應(yīng)用程序

??《ASP.ENT Core 與 RESTful API 開發(fā)實(shí)戰(zhàn)》(第3章)-- 讀書筆記(中)_依賴注入_02??


本文摘自 :https://blog.51cto.com/u

開通會(huì)員,享受整站包年服務(wù)立即開通 >