如何在 asp.net core 3.x 的 startup.cs 檔案中獲取注入的服務
阿新 • • 發佈:2020-06-29
### 一、前言
從 18 年開始接觸 .NET Core 開始,在私底下、工作中也開始慢慢從傳統的 mvc 前後端一把梭,開始轉向 web api + vue,之前自己有個半成品的 asp.net core 2.2 的專案模板,最近幾個月的時間,私下除了學習 Angular 也在對這個模板基於 asp.net core 3.1 進行慢慢補齊功能
因為涉及到底層框架大版本升級,由於某些 breaking changes 必定會造成之前的某些寫法沒辦法繼續使用,趁著端午節假期,在改造模板時,發現沒辦法通過建構函式注入的形式在 `Startup` 檔案中注入某些我需要的服務了,因此本篇文章主要介紹如何在 asp.net core 3.x 的 startup 檔案中獲取注入的服務
### 二、Step by Step
#### 2.1、問題案例
這個問題的發現源於我需要改造模型驗證失敗時返回的錯誤資訊,如果你有嘗試的話,在 3.x 版本中你會發現在 `Startup` 類中,我們沒辦法通過建構函式注入的方式再注入任何其它的服務了,這裡僅以我的程式碼中需要解決的這個問題作為案例
在定義介面時,為了降低後期調整的複雜度,在接收引數時,一般會將引數包裝成一個 dto 物件(data transfer object - 資料傳輸物件),不管是提交資料,還是查詢資料,對於這個 dto 中的某些屬性,都會存在一定的卡控,例如 xxx 欄位不能為空了,xxx 欄位的長度不能超過 30
而在 asp.net core 中,因為會自動進行模型驗證,當不符合 dto 中的屬性要求時,介面會自動返回錯誤資訊,預設的返回資訊如下圖所示
![模型驗證失敗](https://img2020.cnblogs.com/blog/1310859/202006/1310859-20200627104652359-1243794665.png)
可以看到,因為這裡其實是按照 rfc7231這個 RFC 協議返回的錯誤資訊,這個並不符合我的要求,因此這裡我需要改寫這個返回的錯誤資訊
自定義 asp.net core 的模型驗證錯誤資訊方法有很多種,我的實現方法如下,因為我需要記錄請求的標識 Id 和錯誤日誌,所以這裡我需要將 `ILogger` 和 `IHttpContextAccessor` 注入到 `Startup` 類中
```csharp
///
/// 修改模型驗證錯誤返回資訊
///
/// 服務容器集合
/// 日誌記錄例項
///
///
public static IServiceCollection AddCustomInvalidModelState(this IServiceCollection services,
ILogger logger, IHttpContextAccessor httpContextAccessor)
{
services.Configure(options =>
{
options.InvalidModelStateResponseFactory = actionContext =>
{
// 獲取驗證不通過的欄位資訊
//
var errors = actionContext.ModelState.Where(e => e.Value.Errors.Count > 0)
.Select(e => new ApiErrorDto
{
Title = "請求引數不符合欄位格式要求",
Message = e.Value.Errors.FirstOrDefault()?.ErrorMessage
}).ToList();
var result = new ApiReturnDto