ASP.NET Core 依賴(lài)注入詳細(xì)
前言:
ASP.NET Core
應(yīng)用在啟動(dòng)過(guò)程中會(huì)依賴(lài)各種組件提供服務(wù),而這些組件會(huì)以接口的形式標(biāo)準(zhǔn)化,這些組件這就是我們所說(shuō)的服務(wù),ASP.NET Core
框架建立在一個(gè)底層的依賴(lài)注入框架之上,它使用容器提供所需的服務(wù)。要了解依賴(lài)注入容器以及它的機(jī)制,我們需要了解什么是依賴(lài)注入。
一、控制反轉(zhuǎn)
說(shuō)道依賴(lài)注入就不得不提控制反轉(zhuǎn)(IoC)。
定義: 高層模塊不應(yīng)該依賴(lài)低層模塊,二者都應(yīng)該依賴(lài)其抽象;抽象不應(yīng)該依賴(lài)細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴(lài)抽象。
相對(duì)于細(xì)節(jié)的多變性,抽象的東西要穩(wěn)定的多。以抽象為基礎(chǔ)搭建起來(lái)的架構(gòu)比以細(xì)節(jié)為基礎(chǔ)搭建起來(lái)的架構(gòu)要穩(wěn)定的多。在.NET
中,抽象指的是接口或者抽象類(lèi),細(xì)節(jié)就是具體的實(shí)現(xiàn)類(lèi),使用接口或者抽象類(lèi)的目的是制定好規(guī)范和契約,而不去涉及任何具體的操作,把展現(xiàn)細(xì)節(jié)的任務(wù)交給他們的實(shí)現(xiàn)類(lèi)去完成。
二、好萊塢法則
“不要給我們打電話,我們會(huì)給你打電話(don‘t call us, we‘ll call you
)”這是著名的好萊塢原則。在好萊塢,把簡(jiǎn)歷遞交給演藝公司后就只有回家等待。由演藝公司對(duì)整個(gè)娛樂(lè)項(xiàng)的完全控制,演員只能被動(dòng)式的接受公司的差使,在需要的環(huán)節(jié)中,完成自己的演出。IIOC
的原理就是基于好萊塢原則,所有的組件都是被動(dòng)的(Passive
),所有的組件初始化和調(diào)用都由容器負(fù)責(zé)。
以ASP.NET MVC
開(kāi)發(fā)來(lái)說(shuō),我們只需按照約定的規(guī)則(定義好的目錄或命名規(guī)則)定義對(duì)應(yīng)的controller
和View
文件即可。整個(gè)框架會(huì)根據(jù)路由規(guī)則解析的參數(shù)到目標(biāo)Controller
,如果目標(biāo)Action
方法需要呈現(xiàn)一個(gè)View
,框架會(huì)根據(jù)約定找到對(duì)應(yīng)的的View
文件( .cshtml
文件),對(duì)其進(jìn)行動(dòng)態(tài)編譯生成html回復(fù)給客戶(hù)端,整個(gè)框架都體現(xiàn)了IoC
思想。
三、流程控制
IoC
是將流程的控制從應(yīng)用程序當(dāng)中遷移到框架當(dāng)中,框架利用一個(gè)引擎驅(qū)動(dòng)整個(gè)流程的自動(dòng)執(zhí)行。應(yīng)用程序無(wú)須關(guān)心工作流程的細(xì)節(jié),它只需要啟動(dòng)這個(gè)引擎即可。框架會(huì)以替丁的形式提供擴(kuò)展點(diǎn),應(yīng)用程序通過(guò)注冊(cè)擴(kuò)展的方式實(shí)現(xiàn)對(duì)某個(gè)環(huán)節(jié)的控制。一旦這個(gè)引擎(容器)被啟動(dòng),注冊(cè)的擴(kuò)展就會(huì)自動(dòng)參與整個(gè)流程的執(zhí)行。
通過(guò)上面這張圖不難看出IoC在其中起到的作用。
未使用前: 整個(gè)程序相互依賴(lài),當(dāng)新的需求被提出時(shí),牽一發(fā)而動(dòng)全身,這是我們最不想看到的,在小項(xiàng)目中還能理清關(guān)系,當(dāng)需求越來(lái)越多,簡(jiǎn)直不可想象。
開(kāi)始使用: 在引入第三方后,各個(gè)模塊之間沒(méi)有耦合關(guān)系,將依賴(lài)降至最低,所有控制都通過(guò)IoC集中控制。
使用后: 為了方便觀察把中間的IoC容器拿掉后,可以看出各個(gè)模塊之間已經(jīng)沒(méi)有耦合關(guān)系,修改單一模塊后,再也不需要考慮其他模塊。
四、三種依賴(lài)注入方式
1.構(gòu)造器注入
構(gòu)造器注入就是在構(gòu)造函數(shù)中借助參數(shù)將依賴(lài)的對(duì)象注入由他創(chuàng)建的對(duì)象當(dāng)中。平時(shí)基本都是使用其中的構(gòu)造函數(shù)方式實(shí)現(xiàn)注入。
public class A { public IB B { get; } public A(IB b) => B = b; }
ASP.NET Core 中的使用
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }
2.屬性注入
通過(guò)標(biāo)注InjectionAttribute
特性的方式可以將屬性設(shè)置為自動(dòng)注入的依賴(lài)屬性。
public class A { public IB B { get; set; } [Injection] public IC C { get; set; } }
3.方法注入
同樣通過(guò)標(biāo)注InjectionAttribute
特性的方式可以將該方法標(biāo)注為注入方法。
public class A { public IB B { get; } [Injection] public Initialize(IB b) => B = b; }
除了通過(guò)容器初始化服務(wù)過(guò)程中自動(dòng)調(diào)用實(shí)現(xiàn),我們還可以利用它實(shí)現(xiàn)另一種更加自由的方法注入,這種方式在ASP.NET Core
中廣范應(yīng)用。在ASP.NET Core
啟動(dòng)時(shí)會(huì)調(diào)用Startup
對(duì)象完成中間件注冊(cè),而定義Startup類(lèi)型時(shí)候不需要讓他實(shí)現(xiàn)某個(gè)接口,所以注冊(cè)Configure
方法沒(méi)有一個(gè)固定聲明,但可以通過(guò)下面方法將任意依賴(lài)服務(wù)注冊(cè)到這個(gè)方法當(dāng)中。
public class Startup { public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication1 v1")); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
五、生命周期
AddSingleton的生命周期: 項(xiàng)目啟動(dòng)-項(xiàng)目關(guān)閉 相當(dāng)于靜態(tài)類(lèi) 只會(huì)有一個(gè)
AddScoped的生命周期: 請(qǐng)求開(kāi)始-請(qǐng)求結(jié)束 在這次請(qǐng)求中獲取的對(duì)象都是同一個(gè)
AddTransient的生命周期: 請(qǐng)求獲取-(GC回收-主動(dòng)釋放) 每一次獲取的對(duì)象都不是同一個(gè)
注意:由于AddScoped
對(duì)象是在請(qǐng)求的時(shí)候創(chuàng)建的,所以不能在AddSingleton
對(duì)象中使用,甚至也不能在AddTransient
對(duì)象中使用。
權(quán)重: AddSingleton→AddTransient→AddScoped
六、ASP.Net Core 中自帶的注入
public void ConfigureServices(IServiceCollection services) { services.AddScoped<IA, A>; services.AddSingleton<IB, B>; services.AddTransient<IC, C>; services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication1", Version = "v1" }); }); }
注意: ASP.Net Core
中的注入還是比較簡(jiǎn)單的,但是當(dāng)服務(wù)變得越來(lái)越多時(shí),手動(dòng)注入就比較麻煩了,后續(xù)在介紹其他IoC框架。
到此這篇關(guān)于ASP.NET Core 依賴(lài)注入詳細(xì)的文章就介紹到這了,更多相關(guān) ASP.NET Core 依賴(lài)注入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
.net中線程同步的典型場(chǎng)景和問(wèn)題剖析
在使用多線程進(jìn)行編程時(shí),有一些經(jīng)典的線程同步問(wèn)題,對(duì)于這些問(wèn)題,.net提供了多種不同的類(lèi)來(lái)解決2012-11-11asp.net mvc路由篇 如何找到 IHttpHandler方法介紹
學(xué)習(xí)是使用asp.net已經(jīng)有很長(zhǎng)一段時(shí)間了,現(xiàn)在就來(lái)分析一下mvc的整過(guò)過(guò)程吧。個(gè)人計(jì)劃寫(xiě)一個(gè)mvc系列的博文,僅從源代碼的角度來(lái)分析mvc。在接觸mvc時(shí)我們一定會(huì)經(jīng)歷路由,那么路由這東東是怎么搞出來(lái)的啊2012-11-11.Net性能調(diào)優(yōu)-ArrayPool詳情
ArrayPool具有高性能 托管 數(shù)組緩沖池,可重復(fù)使用,用 租用 空間的方式代替 重新分配 數(shù)組空間的行為的特點(diǎn)及可以在頻繁創(chuàng)建和銷(xiāo)毀數(shù)組的情況下 提高性能 ,減少垃圾回收器的壓力的優(yōu)點(diǎn),下面文章內(nèi)容將詳細(xì)對(duì)其做介紹,需要的朋友可以參考一下2021-09-09.Net?Core?配置文件讀取IOptions,IOptionsMonitor,IOptionsSnapshot
這篇文章主要介紹了.Net?Core配置文件讀取IOptions,IOptionsMonitor,IOptionsSnapshot,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09為什么ASP.NET Core 數(shù)據(jù)庫(kù)連接串的值和appsettings.json配的不一樣?
這篇文章主要介紹了為什么數(shù)據(jù)庫(kù)連接串的值和appsettings.json配的不一樣?下面我們就帶著疑問(wèn)閱讀下文,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-02-02.NET?中配置從xml轉(zhuǎn)向json方法示例詳解
這篇文章主要為大家介紹了.NET?中配置從xml轉(zhuǎn)向json方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11