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

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

生活随笔

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

asp.net

.NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入

發(fā)布時(shí)間:2023/12/4 asp.net 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本節(jié)內(nèi)容為控制反轉(zhuǎn)與依賴注入

簡(jiǎn)介

控制反轉(zhuǎn)IOC

這個(gè)內(nèi)容事實(shí)上在我們的C#高級(jí)篇就已經(jīng)有所講解,控制反轉(zhuǎn)是一種設(shè)計(jì)模式,你可以這樣理解控制反轉(zhuǎn),假設(shè)有一個(gè)人他有一部A品牌手機(jī),他用手機(jī)進(jìn)行聽(tīng)歌、打游戲,那么你可以創(chuàng)建一個(gè)手機(jī)類和一個(gè)人類

class APhone : IPhone {public string Owner{get;set;}public Phone(string own){Owner = own;}void Play(){}void Music(){} } class Man {public string Name{get;set;}void Game(){var p = new APhone(Name);p.Play();} }

事實(shí)上這段代碼的耦合度是比較高的?它使用的是正轉(zhuǎn),也就是我需要什么東西的時(shí)候我就自己創(chuàng)建一個(gè)這個(gè)東西。為什么說(shuō)他不好呢,如果有一天這個(gè)人決定再也不使用A品牌手機(jī)了,他決定以后只使用B品牌。那么也就意味著整個(gè)的Man類使用過(guò)APhone類的地方都需要更改。這是一個(gè)非常麻煩的事情,我們這個(gè)時(shí)候就需要運(yùn)用我們的IOC控制反轉(zhuǎn)了。我們將實(shí)例或者是需要使用的對(duì)象的創(chuàng)建交給你的調(diào)用者,自己只負(fù)責(zé)使用,其它人丟給你依賴的這個(gè)過(guò)程理解為注入。

控制反轉(zhuǎn)的核心就是——原本我保存使用我自己的東西,現(xiàn)在我把控制權(quán)交給我的上級(jí),我需要使用的時(shí)候再向他要。這個(gè)時(shí)候,接口的作用不言而喻,A繼承了Phone接口,B也繼承了,假定我們一開(kāi)始就使用Phone接口去創(chuàng)建不同的A,B對(duì)象,那么是不是可以有效的切換AB對(duì)象呢?

依賴注入

依賴注入體現(xiàn)的是一個(gè)IOC(控制反轉(zhuǎn)),它非常的簡(jiǎn)單,我們之前的Man類代碼中使用的是正轉(zhuǎn)的方式,也就是我要一個(gè)對(duì)象,那么我就創(chuàng)建一個(gè)。現(xiàn)在我們使用依賴注入就是將我們對(duì)這個(gè)對(duì)象的控制權(quán)交給上一級(jí)接口,也就成為了這種,我想要一個(gè)對(duì)象,我就向上級(jí)發(fā)出請(qǐng)求,上級(jí)就給我創(chuàng)建了一個(gè)對(duì)象。我們通常使用構(gòu)造函數(shù)注入的方式進(jìn)行依賴的注入。

上文的代碼就會(huì)變成

class Man {private readonly IPhone _phone;public Man(IPhone phone){_phone = phone;} }

假設(shè)這個(gè)時(shí)候你需要將手機(jī)換成B品牌,那么只需要再注入的地方傳入B品牌的對(duì)象即可了。

容器

但是現(xiàn)在又出現(xiàn)了一個(gè)新的問(wèn)題,假設(shè)說(shuō)這個(gè)類有100個(gè)使用該接口的依賴,如果,我們是不是要在100個(gè)地方做這樣的事情?控制是反轉(zhuǎn)了,依賴的創(chuàng)建也移交到了外部。現(xiàn)在的問(wèn)題是依賴太多,我們需要一個(gè)地方統(tǒng)一管理系統(tǒng)中所有的依賴,這個(gè)時(shí)候,我們就使用容器進(jìn)行集中的管理

容器負(fù)責(zé)兩件事情:

  • 綁定服務(wù)與實(shí)例之間的關(guān)系

  • 獲取實(shí)例,并對(duì)實(shí)例進(jìn)行管理(創(chuàng)建與銷毀)

使用

說(shuō)了那么多,我們?nèi)绾卧?NET Core中使用我們的依賴注入呢?這里我們針對(duì)的是所有的.NET Core的應(yīng)用,在.NET Core中依賴注入的核心分為兩個(gè)組件:位于Microsoft.Extensions.DependencyInjection命名空間下的IServiceCollection和 IServiceProvider。

其中

  • IServiceCollection 負(fù)責(zé)注冊(cè)

  • IServiceProvider 負(fù)責(zé)提供實(shí)例

在默認(rèn)的容器ServiceCollection中有三個(gè)方法

  • .AddTransient<I,C>()

  • .AddSingleton<I,C>()

  • .AddScoped<I,C>()

這里就不得不提一下我們依賴注入的三種生命周期了

  • Singleton指的是單例模式,也就是說(shuō),在整個(gè)程序運(yùn)轉(zhuǎn)期間只會(huì)生成一次

  • Transient指每一次GetService都會(huì)創(chuàng)建一個(gè)新的實(shí)例

  • Scope指在同一個(gè)Scope內(nèi)只初始化一個(gè)實(shí)例 ,可以理解為( 每一個(gè)request級(jí)別只創(chuàng)建一個(gè)實(shí)例,同一個(gè)http request會(huì)在一個(gè) scope內(nèi))

我們可以嘗試使用控制臺(tái)項(xiàng)目來(lái)模擬依賴注入的原理,也就是說(shuō)我們直接從容器獲取我們對(duì)象實(shí)例,并且我們使用Guid進(jìn)行唯一性的標(biāo)記。

interface IPhoneScope{Guid Guid { get; }}interface IPhoneSingleton{Guid Guid { get; }}interface IPhoneTransient{Guid Guid { get; }}class PhoneService:IPhoneScope,IPhoneSingleton,IPhoneTransient{public PhoneService(){this._guid = Guid.NewGuid();}public PhoneService(Guid guid){this._guid = guid;}private Guid _guid;public Guid Guid =&gt; this._guid;}

然后,在我們的主函數(shù)中

namespace DI_AND_IOC {class Program{static void Main(string[] args){var services = new ServiceCollection().AddScoped&lt;IPhoneScope, PhoneService&gt;().AddTransient&lt;IPhoneTransient, PhoneService&gt;().AddSingleton&lt;IPhoneSingleton, PhoneService&gt;();var provider = services.BuildServiceProvider();using (var scope = provider.CreateScope()){var p = scope.ServiceProvider;var scopeobj1 = p.GetService&lt;IPhoneScope&gt;();var transient1 = p.GetService&lt;IPhoneTransient&gt;();var singleton1 = p.GetService&lt;IPhoneSingleton&gt;();var scopeobj2 = p.GetService&lt;IPhoneScope&gt;();var transient2 = p.GetService&lt;IPhoneTransient&gt;();var singleton2 = p.GetService&lt;IPhoneSingleton&gt;();Console.WriteLine($"scope1: {scopeobj1.Guid},\n" +$"transient1: {transient1.Guid}, \n" +$"singleton1: {singleton1.Guid}\n");Console.WriteLine($"scope2: {scopeobj2.Guid}, \n" +$"transient2: {transient2.Guid},\n" +$"singleton2: {singleton2.Guid}\n");}using (var scope = provider.CreateScope()){var p = scope.ServiceProvider;var scopeobj3 = p.GetService&lt;IPhoneScope&gt;();var transient3 = p.GetService&lt;IPhoneTransient&gt;();var singleton3 = p.GetService&lt;IPhoneSingleton&gt;();Console.WriteLine($"scope3: {scopeobj3.Guid}, \n" +$"transient3: {transient3.Guid},\n" +$"singleton3: {singleton3.Guid}");}}} }

你應(yīng)該會(huì)得到類似以下的數(shù)據(jù)

scope1: 096d38e5-0c7b-4e50-9c79-241fb18a56ed, transient1: 289ebd11-8159-4f22-b53e-ed738a317313, singleton1: b453b7f5-3594-4b66-99c8-a72763abaa83scope2: 096d38e5-0c7b-4e50-9c79-241fb18a56ed, transient2: 212ad420-e54c-4dd6-9214-abe91aacdd9c, singleton2: b453b7f5-3594-4b66-99c8-a72763abaa83scope3: 688b6ffd-a8c1-47f4-a20a-872c2285d67c, transient3: 3d09997d-fffb-43d1-9e53-ccf9771c819d, singleton3: b453b7f5-3594-4b66-99c8-a72763abaa83

可以發(fā)現(xiàn),singleton對(duì)象是不會(huì)發(fā)生改變的,而scope對(duì)象在創(chuàng)建新的scope之后就發(fā)生了改變,而transient對(duì)象每一次請(qǐng)求都在發(fā)生改變。

需要注意的是,在控制臺(tái)項(xiàng)目使用容器服務(wù)需要引入 *** Microsoft.Extensions.DependencyInjection *** 程序集,你可以在引入中導(dǎo)入該dll

通過(guò)對(duì)注入服務(wù)的生命周期管控,在一些ASP.NET Core項(xiàng)目中,有些類(服務(wù))有可能跨越了多個(gè)Action或者Controller,那么我們正確的使用生命周期,我們可以盡可能的節(jié)省內(nèi)存,即能減少實(shí)例初始化的消耗。

在ASP.NET Core中的使用

在ASP.NET Core中,我們使用依賴注入非常的簡(jiǎn)單,在StartUp類中的ConfigureServices方法中已經(jīng)為我們構(gòu)建好了容器,我們只需要做類似于這樣的操作

services.AddScoped&lt;IPhoneScope, PhoneService&gt;(); services.AddDbContext&lt;DbContext&gt;(); services.AddMVC();

如果你需要在控制器中注入服務(wù),官方的推薦方案是使用構(gòu)造函數(shù)注入

public IPhoneScope _ips; public Controller(IPhoneScope ips) {_ips = ips; }

特別的,你如果使用MVC的Razor頁(yè)面進(jìn)行注入的話,那么輸入以下指令

如果我的文章幫助了您,請(qǐng)您在github.NETCoreGuide項(xiàng)目幫我點(diǎn)一個(gè)star,在博客園中點(diǎn)一個(gè)關(guān)注和推薦。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的.NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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