在這個視頻中,我們將通過一個例子詳細討論依賴注入。
public class HomeController : Controller
{
private IStudentRepository _studentRepository;
//使用構造函數注入的方式注入IStudentRepository
public HomeController(IStudentRepository studentRepository)
{
_studentRepository = studentRepository;
}
//返回學生的名字
public string Index()
{
return _studentRepository.GetStudent(1).Name;
}
}
注意事項 :
HomeController依賴於IStudentRepository來 查詢 Student 數據。
我們使用構造函數將IStudentRepository實例注入HomeController,而不是HomeController對IStudentRepository接口創建新的實例化。
這稱為構造函數注入,因為我們使用構造函數來注入依賴項。
請注意,我們將注入的依賴項分配給只讀欄位readonly。這是一個很好的做法,因為它可以防止在方法中誤操作地為其分配另一個值,比如 null。
此時,如果我們運行項目,則會收到以下錯誤:
InvalidOperationException: Unable to resolve service for type 'StudentManagement.Model.IStudentRepository'
while attempting to activate 'StudentManagement.Controllers.HomeController'.
IStudentRepository可能有多個實現。在我們的項目中,我們只有一個實現,那就是MockStudentRepository
顧名思義,MockStudentRepository使用內存中的學生模擬數據。
在我們即將發布的視頻中,我們將討論為IStudentRepository提供另一個實現,該實現從 SQL Server 資料庫中查詢學生數據。
現在,讓我們使用MockStudentRepository。
要修復 InvalidOperationException 錯誤,我們需要在 ASP.NET Core 中使用依賴注入容器註冊MockStudentRepository類。
我們在 Startup 類的 ConfigureServices()方法中執行此操作
ASP.NET Core 提供以下 3 種方法來使用依賴項注入容器註冊服務。我們使用的方法決定了註冊服務的生命周期。
AddSingleton()方法創建一個Singleton服務。首次請求時會創建Singleton服務。然後,所有後續請求都使用相同的實例。通常,每個應用程式只創建一次Singleton服務,並且在整個應用程式生命周期中使用該單個實例。
AddTransient() 方法可以稱作:暫時性模式,會創建一個 Transient 服務。每次請求時,都會創建一個新的 Transient 服務實例,通常,在一些泛型的場景中使用。如:
Microsoft.Extensions.Options.IConfigureOptions<T>;
AddScoped()方法創建一個 Scoped 服務。在我們發起的每個請求中都會創建一個新的 Scoped 服務實例。例如,在 Web 應用程式中,它為每個 http 請求創建 1 個實例,但在同一 Web 請求中的其他服務在調用這個請求的時候,都會使用相同的實例。注意,它在一個客戶端請求中是相同的,但在多個客戶端請求中是不同的。
請不要擔心,如果這一點有點令人困惑。我們將在本系列即將發布的視頻中好好單獨講這三種方法。
現在,要修復 InvalidOperationException 錯誤,讓我們使用AddSingleton()向 ASP.NET Core 依賴注入容器註冊MockStudentRepository類方法如下圖所示。
所以在此代碼中,如果有人調用IStudentRepository,將調用MockStudentRepository的實例服務。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IStudentRepository, MockStudentRepository>();
}
在這一點上,您可能在想,為什麼我們必須做這一切。為什麼我們不能使用 new 關鍵字在 HomeController 中簡單地創建MockStudentRepository類的實例,如下所示。
public class HomeController : Controller
{
private readonly IStudentRepository _studentRepository;
//使用構造函數注入的方式注入IStudentRepository
public HomeController(IStudentRepository studentRepository)
{
_studentRepository = new MockStudentRepository();
}
//返回學生的名字
public string Index()
{
return _studentRepository.GetStudent(1).Name;
}
}
這使HomeController與MockStudentRepository緊密耦合。 稍後如果我們為IStudentRepository 提供新的實現,並且如果我們想要使用新的實現而不是MockStudentRepository,我們必須更改 HomeController 中的代碼。您可能會想,這只是一行代碼更改,所以這並不難。
那麼,如果我們在我們的應用程式中的 50 個其他控制器中使用了這個MockStudentRepository呢? 所有 50 個控制器中的代碼都必須更改。這不僅無聊而且容易出錯。
簡而言之,使用 new 關鍵字創建依賴關係的實例會產生緊密耦合,因此您的應用程式將很難更改。通過依賴注入,我們不會有這種緊密耦合。
使用依賴注入,即使我們在我們的應用程式中的 50 個其他控制器中使用了MockStudentRepository,如果我們想用不同的實現交換它,我們只需要在 Startup.cs 文件中更改以下一行代碼。請注意,我們現在使用DatabaseStudentRepository而不是MockStudentRepository。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IStudentRepository, DatabaseStudentRepository>();
}
這樣帶來的效果是單元測試也變得更加容易,因為我們可以通過依賴注入輕鬆地交換依賴項。 如果這有點令人困惑,請不要擔心。我們將在即將發布的視頻中為IStudentRepository提供不同的實現。此新實現將從 SQL Server 資料庫中查詢數據。然後,我們將使用DatabaseStudentRepository實現替換MockStudentRepository實現。那個時候,您將了解依賴注入提供的功能和靈活性。
如果您覺得我的文章質量還不錯,歡迎打賞,也可以訂閱我的視頻哦
未得到授權不得擅自轉載本文內容,52abp.com保留版權
文字版目錄:https://www.52abp.com/Wiki/mvc/latest/1.Intro
交流QQ群:952387474《微軟MVP帶你學ASP.NET CORE》
視頻課程: https://ke.qq.com/course/392589?tuin=2522cdf3