ASP.NET Core 中的依赖注入
什么是依賴注入
軟件設計原則中有一個依賴倒置原則(DIP),為了更好的解耦,講究要依賴于抽象,不要依賴于具體。而控制反轉(Ioc)就是這樣的原則的其中一個實現思路, 這個思路的其中一種實現方式就是依賴注入(DI)。
什么是依賴:當一個類需要另一個類協作來完成工作的時候就產生了依賴。
什么是注入: 注入體現的是一個IOC(控制反轉的的思想)。正轉是自己來實例化需要的依賴。反轉是類不應該自己創建它,而是應該由它的調用者傳給它。于是可以通過構造函數等讓外界把依賴傳給類。
為什么要反轉?為了在業務變化的時候盡少改動代碼可能造成的問題?;诔橄筇砑有碌膶崿F。只需要在原來注入的地方改一下就可以了。
什么是容器?容器統一管理系統中的所有依賴。容器負責兩件事情:
綁定服務與實例之間的映射關系
獲取實例并對實例進行管理(創建與銷毀)
ASP .NET Core 中使用依賴注入
IServiceCollection?負責注冊服務,是一個IList
IServiceProvider?負責提供實例,是由IServiceCollection的擴展方法BuildServiceProvider創建的。
ServiceDescriptor?單個服務描述
Type ServiceType: 服務的類型
Type ImplementationType: 實現的類型
ServiceLifetime Lifetime: 服務的生命周期
object ImplementationInstance: 實現服務的實例
Func<IServiceProvider, object> ImplementationFactory: 創建服務實例的工廠
注冊
ServiceCollection提供了三種注冊方法分別對應著三種實例生命周期。
AddSingleton?整個應用程序生命周期以內只創建一個實例
AddScoped?在同一個Scope內只初始化一個實例,可以理解為( 每一個request級別只創建一個實例,同一個http request會在一個 scope內)
AddTransient?每一次GetService都會創建一個新的實例
做一個簡單測試:
創建測試類:
在ConfigureServices里注冊
通過三種方法來獲取這個Test類實例, Controller和View中代碼如下
運行,結果如下
03d437d6-2f18-452e-a7fd-ce62cea9038108b31487-b02b-4d62-bc2b-6d2026389f0c21a7fc13-6e7b-4590-910b-68d21a7a03d1說明三種方式獲取了三個不同的實例, 刷新一下頁面, 又變成了另外三個不同的值.
現在在startup文件中將原來的 services.AddTransient<ITest,Test>() 改為 services.AddScoped<ITest,Test>() , 其他不變, 重新運行一下, 結果如下
050fef7e-2dc3-4d7d-8733-683b54b40b0b050fef7e-2dc3-4d7d-8733-683b54b40b0b050fef7e-2dc3-4d7d-8733-683b54b40b0b刷新一下:
c9e5df8d-b085-4e3a-b883-fa083ba1d136 c9e5df8d-b085-4e3a-b883-fa083ba1d136 c9e5df8d-b085-4e3a-b883-fa083ba1d136三組數字相同, 刷新一下, 又變成了另外三組一樣的值, 這說明在同一次請求里, 獲取的實例是同一個。
最常用的DBContext默認構建為Scope實例。即能減少實例初始化的消耗,還能實現跨Service事務的功能。
再將 services.AddScoped<ITest,Test>() 改為 services.AddSingleton<ITest,Test>() , 重新運行, 這次結果是
42ef5162-5781-427b-ac9d-a152500ed32f 42ef5162-5781-427b-ac9d-a152500ed32f 42ef5162-5781-427b-ac9d-a152500ed32f發現三組值是一樣的, 說明獲得的是同一個實例, 在刷新一下頁面, 仍然是這三組值, 說明多次請求獲得的結果也是同一個實例.
使用
在Startup類ConfigureService中初始化
- public void ConfigureServices(IServiceCollection services){services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);services.AddTransient<ITest, Test>();}
方法中默認調用了services.AddMvc(), 是IServiceCollection的一個擴展方法 public static IMvcBuilder AddMvc(this IServiceCollection services), 作用就是向這個清單中添加了一些MVC需要的服務,例如Authorization、RazorViewEngin、DataAnnotations等。
Controller中使用
private ITest _test;private ILogger<HomeController> _logger;public HomeController(ITest test, ILogger<HomeController> logger){ ? ?this._test = test; ? ?this._logger = logger; }通過HttpContext來獲取實例
HttpContext.RequestServices.GetService<ITest>()
HttpContext下有一個RequestedService同樣可以用來獲取實例對象,不過這種方法一般不推薦。需要添加Microsoft.Extension.DependencyInjection的using來調用這個方法的。View中使用
@inject ITest TestFromView<ul> <li>@TestFromView.Guid</li> </ul>
在View中通過@inject聲明
釋放
對于每次請求, 我們最初配置的根IServiceProvider通過CreateScope()創建了一個新的IServiceScope, 而這個IServiceScope的ServiceProvider屬性將負責本次該次請求的服務提供, 當請求結束, 這個ServiceProvider的dispose會被調用。
在2.0中, ServiceProvider只調用由它創建的 IDisposable 類型的 Dispose。 如果將一個實例添加到容器,它將不會被釋放。
例如:
替換為其它的 Ioc 容器
可以將默認的容器改為其他的容器, 比如Autofac, 需要把Startup類里面的 ConfigureService的 返回值從 void改為 IServiceProvider即可。而返回的則是一個AutofacServiceProvider。
參考
Dependency injection in ASP.NET Core
全面理解 ASP.NET Core 依賴注入
ASP.NET Core 2.0 : 六. 舉個例子來聊聊它的依賴注入
ASP.NET Core中的依賴注入(1):控制反轉(IoC)
ASP.NET Core 2.0使用Autofac實現IOC依賴注入竟然能如此的優雅簡便
ASP.NET Core依賴注入最佳實踐,提示&技巧
把舊系統遷移到.Net Core 2.0 日記(2) - 依賴注入/日志NLog
ASP.NET Core依賴注入深入討論
在.NET Core中處理一個接口多個不同實現的依賴注入問題
ASP.NET Core 2.0 依賴注入
AspectCore中的IoC容器和依賴注入
ASP.NET Core依賴注入解讀&使用Autofac替代實現
原文地址:https://www.cnblogs.com/royzshare/p/9440914.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的ASP.NET Core 中的依赖注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core Middlew
- 下一篇: 【活动(广州)】office365的开发