日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

.Net Core3.0依赖注入DI

發(fā)布時(shí)間:2023/12/4 asp.net 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net Core3.0依赖注入DI 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

構(gòu)建ASP.NET Core應(yīng)用程序的時(shí)候,依賴注入已成為了.NET Core的核心,這篇文章,我們理一理依賴注入的使用方法。

不使用依賴注入

?首先,我們創(chuàng)建一個(gè)ASP.NET Core Mvc項(xiàng)目,定義個(gè)表達(dá)的愛(ài)服務(wù)接口,中國(guó)小伙類(lèi)實(shí)現(xiàn)這個(gè)類(lèi)如下:

public interface ISayLoveService { string SayLove(); } public class CNBoyService : ISayLoveService { public string SayLove() { return "安紅,我喜歡你"; } }

在LoveController 控制器中調(diào)用 ISayLoveService的SayLove方法。

public class LoveController : Controller

{ private??ISayLoveService?loveService;????? public?IActionResult?Index() { loveService = new CNBoyService(); //中國(guó)小伙對(duì)安紅的表達(dá) ViewData["SayLove"] = loveService.SayLove(); return View(); } }

輸出如圖:

小結(jié):LoveController控制器調(diào)用ISayLoveService服務(wù)的SayLove方法;我們的做法,直接在控制器去new CNBoyService()實(shí)例對(duì)象,也就是LoveController依賴ISayLoveService類(lèi)。

思考:能不能有種模式,new實(shí)例不要在使用的時(shí)候進(jìn)行創(chuàng)建,而是在外部或者有一個(gè)容器進(jìn)行管理;這不就是ioc思想嗎?好處,代碼的解耦、代碼更好的維護(hù)等等。

使用依賴注入

上面的疑惑,答案是肯定的,有!并且ASP.NET Core 支持依賴關(guān)系注入 (DI) 軟件設(shè)計(jì)模式(當(dāng)然也可以兼容第三方)。我們還使用上面的代碼,

服務(wù)注冊(cè)

?在Startup類(lèi)ConfigureServices方法中注冊(cè)服務(wù)容器中的依賴關(guān)系

? ? ? public void ConfigureServices(IServiceCollection services)

{ services.AddSingleton<ISayLoveService, CNBoyService>(); services.AddControllersWithViews(); }

在LoveControlle控制器中,通過(guò)構(gòu)造函數(shù)注入

private readonly ISayLoveService loveService; public LoveController(ISayLoveService loveService) { this.loveService = loveService; } public IActionResult Index() { ViewData["SayLove"] = loveService.SayLove(); return View(); }

LoveController 正在將ISayLoveService作為依賴項(xiàng)注入其構(gòu)造函數(shù)中,然后在Index方法中使用它。

推薦:

  • 將注入的依賴項(xiàng)分配給只讀字段/屬性(以防止在方法內(nèi)部意外為其分配另一個(gè)值)。

  • 使用接口或基類(lèi)抽象化依賴關(guān)系實(shí)現(xiàn)。

小結(jié):在控制器中,還有幾種使用如:[FromServices] 標(biāo)簽 、 HttpContext.RequestServices.GetService<T>();我們發(fā)現(xiàn)可以使用ASP.NET Core 提供了一個(gè)內(nèi)置的服務(wù)容器 IServiceProvider。服務(wù)只需要在Startup.ConfigureServices?方法中注冊(cè),然后在運(yùn)行時(shí)將服務(wù)注入 到使用它的類(lèi)的構(gòu)造函數(shù)中。框架負(fù)責(zé)創(chuàng)建依賴關(guān)系的實(shí)例,并在不再需要時(shí)對(duì)其進(jìn)行處理。

思考:服務(wù)注冊(cè)的時(shí)候使用的是 AddSingleton,如services.AddSingleton<ISayLoveService, CNBoyService>();還有其他的嗎?

服務(wù)生命周期

服務(wù)注冊(cè)的時(shí)候,ASP.NET Core支持指定三種生命周期如:

  • Singleton 單例

  • Scoped 范圍

  • Transient 短暫的

  • Singleton 僅創(chuàng)建一個(gè)實(shí)例。該實(shí)例在需要它的所有組件之間共享。因此始終使用同一實(shí)例。

    Scoped 每個(gè)范圍創(chuàng)建一個(gè)實(shí)例。在對(duì)應(yīng)用程序的每個(gè)請(qǐng)求上都會(huì)創(chuàng)建一個(gè)范圍,因此每個(gè)請(qǐng)求將創(chuàng)建一次注冊(cè)為Scoped的任何組件。

    Transient 在每次被請(qǐng)求時(shí)都會(huì)創(chuàng)建,并且永不共享。

    為了能夠更好的裂解生命周期的概念,我們把上面代碼稍作改動(dòng),做一個(gè)測(cè)試:

    ISayLoveService 新增個(gè)屬性LoveId,類(lèi)型為guid,

    public interface ISayLoveService { Guid LoveId { get; } string SayLove(); } public?interface?ITransientSayLoveService?:?ISayLoveService { } public?interface?IScopedSayLoveService?:?ISayLoveService { } public?interface?ISingletonSayLoveService?:?ISayLoveService { } public interface ISingletonInstanceSayLoveService : ISayLoveService { }

    BoyService也很簡(jiǎn)單,在構(gòu)造函數(shù)中傳入一個(gè)Guid,并對(duì)它進(jìn)行賦值。

    public class BoyService : ITransientSayLoveService, IScopedSayLoveService, ISingletonSayLoveService, ISingletonInstanceSayLoveService { public BoyService():this(Guid.NewGuid()) { } public?BoyService(Guid?id) { LoveId = id; } public?Guid?LoveId?{?get;?private?set;?} public?string?SayLove() { return LoveId.ToString(); } }

    ?每個(gè)實(shí)現(xiàn)類(lèi)的構(gòu)造函數(shù)中,我們都產(chǎn)生了一個(gè)新的guid,通過(guò)這個(gè)GUID,我們可以判斷這個(gè)類(lèi)到底重新執(zhí)行過(guò)構(gòu)造函數(shù)沒(méi)有.

    服務(wù)注冊(cè)代碼如下:

    public void ConfigureServices(IServiceCollection services) { //生命周期設(shè)置為T(mén)ransient,因此每次都會(huì)創(chuàng)建一個(gè)新實(shí)例。 services.AddTransient<ITransientSayLoveService, BoyService>(); services.AddScoped<IScopedSayLoveService, BoyService>(); services.AddSingleton<ISingletonSayLoveService, BoyService>(); services.AddSingleton<ISingletonInstanceSayLoveService>(new BoyService(Guid.Empty)); services.AddControllersWithViews(); }

    在LifeIndex方法中多次調(diào)用ServiceProvider的GetService方法,獲取到的都是同一個(gè)實(shí)例。

    public IActionResult LifeIndex() { ViewData["TransientSayLove1"] = HttpContext.RequestServices.GetService<ITransientSayLoveService>().SayLove(); ViewData["ScopedSayLove1"] = HttpContext.RequestServices.GetService<IScopedSayLoveService>().SayLove(); ViewData["SingletonSayLove1"] = HttpContext.RequestServices.GetService<ISingletonSayLoveService>().SayLove(); ViewData["SingletonInstanceSayLove1"] = HttpContext.RequestServices.GetService<ISingletonInstanceSayLoveService>().SayLove(); //同一個(gè)HTTP請(qǐng)求 ,在從容器中獲取一次 ViewData["TransientSayLove2"] = HttpContext.RequestServices.GetService<ITransientSayLoveService>().SayLove(); ViewData["ScopedSayLove2"] = HttpContext.RequestServices.GetService<IScopedSayLoveService>().SayLove(); ViewData["SingletonSayLove2"] = HttpContext.RequestServices.GetService<ISingletonSayLoveService>().SayLove(); ViewData["SingletonInstanceSayLove2"] = HttpContext.RequestServices.GetService<ISingletonInstanceSayLoveService>().SayLove(); return View(); }

    我們編寫(xiě)view頁(yè)面,來(lái)展示這些信息如下:

    @{ ViewData["Title"] = "LifeIndex"; } <div class="row"> <div class="panel panel-default"> <div class="panel-heading"> <h2 class="panel-title">Operations</h2> </div> <div class="panel-body"> <h3>獲取第一次</h3> <dl> <dt>Transient1</dt> <dd>@ViewData["TransientSayLove1"] </dd> <dt>Scoped1</dt> <dd>@ViewData["ScopedSayLove1"]</dd> <dt>Singleton1</dt> <dd>@ViewData["SingletonSayLove1"] </dd> <dt>Instance1</dt> <dd>@ViewData["SingletonInstanceSayLove1"]</dd> </dl> <h3>獲取第二次</h3> <dl> <dt>Transient2</dt> <dd>@ViewData["TransientSayLove2"]</dd> <dt>Scoped2</dt> <dd>@ViewData["ScopedSayLove2"]</dd> <dt>Singleton2</dt> <dd>@ViewData["SingletonSayLove2"]</dd> <dt>Instance2</dt> <dd>@ViewData["SingletonInstanceSayLove2"]</dd> </dl> </div> </div> </div>

    運(yùn)行代碼第一次輸出:

    我們發(fā)現(xiàn),在一次請(qǐng)求中,發(fā)現(xiàn)單例、范圍的生命周期的guid 沒(méi)有變化,說(shuō)明分別用的是同一個(gè)對(duì)象,而瞬態(tài)guid不同,說(shuō)明對(duì)象不是一個(gè)。

    刷新之后,查看運(yùn)行效果

    我們發(fā)現(xiàn)通過(guò)刷新之后,單例模式的guid還是跟首次看到的一樣,其他的都不同;

    總結(jié):如果您將組件A注冊(cè)為單例,則它不能依賴已注冊(cè)“作用域”或“瞬態(tài)”生存期的組件。一般而言:組件不能依賴壽命短于其壽命的組件。如果默認(rèn)的DI容器不能滿足項(xiàng)目需求,可以替換成第三方的如功能強(qiáng)大的Autofac。

    總結(jié)

    以上是生活随笔為你收集整理的.Net Core3.0依赖注入DI的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。