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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

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

發布時間:2023/12/4 asp.net 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本節內容為控制反轉與依賴注入

簡介

控制反轉IOC

這個內容事實上在我們的C#高級篇就已經有所講解,控制反轉是一種設計模式,你可以這樣理解控制反轉,假設有一個人他有一部A品牌手機,他用手機進行聽歌、打游戲,那么你可以創建一個手機類和一個人類

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();} }

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

控制反轉的核心就是——原本我保存使用我自己的東西,現在我把控制權交給我的上級,我需要使用的時候再向他要。這個時候,接口的作用不言而喻,A繼承了Phone接口,B也繼承了,假定我們一開始就使用Phone接口去創建不同的A,B對象,那么是不是可以有效的切換AB對象呢?

依賴注入

依賴注入體現的是一個IOC(控制反轉),它非常的簡單,我們之前的Man類代碼中使用的是正轉的方式,也就是我要一個對象,那么我就創建一個。現在我們使用依賴注入就是將我們對這個對象的控制權交給上一級接口,也就成為了這種,我想要一個對象,我就向上級發出請求,上級就給我創建了一個對象。我們通常使用構造函數注入的方式進行依賴的注入。

上文的代碼就會變成

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

假設這個時候你需要將手機換成B品牌,那么只需要再注入的地方傳入B品牌的對象即可了。

容器

但是現在又出現了一個新的問題,假設說這個類有100個使用該接口的依賴,如果,我們是不是要在100個地方做這樣的事情?控制是反轉了,依賴的創建也移交到了外部。現在的問題是依賴太多,我們需要一個地方統一管理系統中所有的依賴,這個時候,我們就使用容器進行集中的管理

容器負責兩件事情:

  • 綁定服務與實例之間的關系

  • 獲取實例,并對實例進行管理(創建與銷毀)

使用

說了那么多,我們如何在.NET Core中使用我們的依賴注入呢?這里我們針對的是所有的.NET Core的應用,在.NET Core中依賴注入的核心分為兩個組件:位于Microsoft.Extensions.DependencyInjection命名空間下的IServiceCollection和 IServiceProvider。

其中

  • IServiceCollection 負責注冊

  • IServiceProvider 負責提供實例

在默認的容器ServiceCollection中有三個方法

  • .AddTransient<I,C>()

  • .AddSingleton<I,C>()

  • .AddScoped<I,C>()

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

  • Singleton指的是單例模式,也就是說,在整個程序運轉期間只會生成一次

  • Transient指每一次GetService都會創建一個新的實例

  • Scope指在同一個Scope內只初始化一個實例 ,可以理解為( 每一個request級別只創建一個實例,同一個http request會在一個 scope內)

我們可以嘗試使用控制臺項目來模擬依賴注入的原理,也就是說我們直接從容器獲取我們對象實例,并且我們使用Guid進行唯一性的標記。

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;}

然后,在我們的主函數中

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}");}}} }

你應該會得到類似以下的數據

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

可以發現,singleton對象是不會發生改變的,而scope對象在創建新的scope之后就發生了改變,而transient對象每一次請求都在發生改變。

需要注意的是,在控制臺項目使用容器服務需要引入 *** Microsoft.Extensions.DependencyInjection *** 程序集,你可以在引入中導入該dll

通過對注入服務的生命周期管控,在一些ASP.NET Core項目中,有些類(服務)有可能跨越了多個Action或者Controller,那么我們正確的使用生命周期,我們可以盡可能的節省內存,即能減少實例初始化的消耗。

在ASP.NET Core中的使用

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

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

如果你需要在控制器中注入服務,官方的推薦方案是使用構造函數注入

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

特別的,你如果使用MVC的Razor頁面進行注入的話,那么輸入以下指令

如果我的文章幫助了您,請您在github.NETCoreGuide項目幫我點一個star,在博客園中點一個關注和推薦。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。