目錄:web
1、什麼是依賴注入cookie
1.一、什麼是依賴?app
1.二、 什麼是注入?async
1.三、依賴注入解決的問題ide
2、服務的生命週期(.Net Core DI)模塊化
3、替換默認服務容器單元測試
3.一、爲何替換默認服務容器?學習
3.二、如何替換服務容器測試
1、什麼是依賴注入ui
一、 什麼是依賴
Rely類
public class Rely { public Task Test(string testMessage) { Console.WriteLine(testMessage); return Task.FromResult(0); } }
Output類
public class Output { Rely rely = new Rely(); public async Task Out() { await rely.Test("這是一個測試消息"); } }
Output類須要Rely類來幫助它實現輸出的功能,這樣Output類對Rely類產生了依賴,能夠理解爲Output依賴於Rely
依賴的一個設計原則:依賴於抽象,而不是具體的實現,這個後面會具體解釋的
二、 什麼是注入
修改Output類
public class Output { private Rely _rely; public Output(Rely rely) { _rely = rely; } public async Task Out() { await _rely.Test("這是一個測試消息"); } }
在這裏Output類不去實例化Rely類,而是經過其餘人傳遞給我,我只用就好。到底怎麼理解注入呢?
簡單來講就是別人對依賴建立實例化,我本身只負責使用,別人建立好了給我使用,這麼一個過程能夠理解爲注入
這裏主要體現了控制反轉 (IoC)的思想,什麼是IOC ?咱們看看下面的圖就好理解了
直接依賴關係在運行的時候A調用B,B調用C,編譯的時候A取決於B,B取決於C。
而在反轉依賴關係中, A能夠調用B實現的抽象上的方法,讓A能夠在運行時調用B,而B又在編譯時依賴於A控制的接口,程序運行時流程跟直接依賴關係同樣。可是插入了接口意味着能夠輕鬆的有不一樣實現
三、 依賴注入解決的問題
依賴注入主要體現了IOC思想,IOC將實現詳細信息編寫爲依賴而且實現了更高級的抽象,所以程序測試性,維護性,模塊化程度都更高了。這也就對應了剛剛的那個設計規則--依賴於抽象,而不是具體的實現。
那麼依賴注入到底解決了哪些問題呢?
問題一:在直接依賴關係中若是A類須要更換爲其餘實現,那麼就必須得修改B類
問題二:若是有多個依賴B類的類,那麼將會實例化多個配置,這樣代碼會比較分散和冗餘
問題三:這種實現方法很難實現單元測試
解決這些問題的辦法:
一:使用了接口抽象話依賴關係的實現,改動實現只須要改動注入的地方便可
二:註冊服務容器中的依賴關係,有多處須要不準多出實例化配置,直接在Startup.ConfigureServices中註冊便可
2、服務的生命週期(.Net Core DI)
在.NET Core中DI的核心分爲兩個組件:IServiceCollection和 IServiceProvider。
在Startup.cs中ConfigureServices中註冊服務
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();//單例生存期 services.AddScoped<IHttpContextAccessor, HttpContextAccessor>();//範圍生存期 services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();//暫時生存期 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
一、 Transient(暫時生存期)--暫時生存期服務是每次從服務容器進行請求時建立的。 這種生存期適合輕量級、 無狀態的服務。
暫時生存期會在每次請求的時候建立一個實例
二、 Scoped(範圍生存期)--範圍生存期服務是每一個客戶端鏈接時建立的一次實例
範圍生存期會在客戶端鏈接時建立一次實例,而後每次請求的實例都是相同的
三、 Singleton(單例生存期)--單例生存期會在程序第一次請求是建立一次實例
單例生存期僅會在第一次鏈接時建立一次實例,全部整個程序使用的實例都是同一個實例
3、替換默認服務容器
一、 爲何替換默認服務容器
咱們能夠首先理解下什麼是服務容器—依賴注入把依賴的建立給了別人,別人建立好了再給咱們使用。那麼在哪裏建立依賴呢?或者說在那裏管理依賴呢?這裏就有了容器這個概念,負責管理系統中全部的依賴。
那麼咱們爲何要替換容器呢?
內置的服務容器足夠實現一些小型的項目或知足大多數的消費者,可是遇到大型的項目就比較麻煩了,依賴較多,內置的服務容器就顯得有點短板了。當咱們遇到這些問題的時候就能夠考慮替換默認服務容器。
二、 如何替換服務容器
這裏咱們說下替換服務容器爲Autofac。
安裝適當的包
在 Startup.ConfigureServices 中配置返回 爲IServiceProvider:
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); // Add other framework services // Add Autofac var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterModule<DefaultModule>(); containerBuilder.Populate(services); var container = containerBuilder.Build(); return new AutofacServiceProvider(container); }
若是要使用第三方容器的話, Startup.ConfigureServices 必須返回 IServiceProvider。
而後咱們在 DefaultModule
中配置 Autofac
public class DefaultModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<CharacterRepository>().As<ICharacterRepository>(); } }
歡迎你們掃描下方二維碼,和我一塊兒學習更多的知識😊