.NET依賴注入IOC你了解嗎?

IOC在Web API 中是經常使用的,但是在一些WPF項目并不是經常使用或者被人熟知的,我把相關依賴注入的內容又做了一次學習和整理

什么是依賴注入?

依賴注入是一種設計模式和軟件設計原則,用于實現 控制反轉。它的核心思想是:將對象所依賴的其他對象的創建和管理職責從對象內部轉移到外部容器或框架,從而降低代碼的耦合度,提高可測試性、可維護性和靈活性。

依賴注入的主要優點

  1. 降低耦合度(Decoupling):
    ○ 組件(如 OrderService)只依賴于接口(如 IOrderRepository),而不依賴于具體實現(如 SqlOrderRepository)。具體實現的切換由外部容器控制。
  2. 提高可測試性(Testability):
    ○ 可以輕松地為依賴項創建 Mock 或 Stub 對象(實現相同的接口),并在測試時注入到被測試對象中。這使得單元測試獨立、快速且可靠(不依賴數據庫、網絡等外部資源)。
  3. 提高可維護性和可擴展性:
    ○ 更容易替換依賴的實現(只需在容器配置中更改綁定關系)。
    ○ 更容易添加新功能(添加新實現并注冊到容器即可)。
    ○ 代碼更清晰,職責更單一。
  4. 促進代碼重用:
    ○ 解耦后的組件更容易在不同的上下文中復用。
  5. 管理對象生命周期:
    ○ DI 容器通常提供對依賴對象生命周期的管理(如單例、每次請求創建新實例、線程內單例等),簡化了資源管理。

NET 項目使用依賴注入

● Microsoft.Extensions.DependencyInjection.Abstractions
● Microsoft.Extensions.Dependencyinjection

核心類型

● IServiceCollection 服務注冊
● ServiceDescriptor 服務注冊時的信息
● IServiceProvider 具體的容器
● IServiceScope 子容器生命周期

生命周期

1.AddSingleton 單例生命周期

● 在整個進程中,多次創建對象都是同一個對象—遵循了單例模式;
● 第一次創建以后,在內存中,保存下來了,下次創建–直接使用內存,而不是再去全新的創建

ServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddSingleton<ITestService, TestService>();
ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();ITestService testService1 = serviceProvider.GetService<ITestService>();
ITestService testService2 = serviceProvider.GetService<ITestService>();bool isflg = object.ReferenceEquals(testService1, testService2);
Console.WriteLine($"testService1==testService2   {isflg}"); //true

2.AddScoped 作用域生命周期

● 每一個作用域(serviceProvider)內創建的某一個類的對象是同一個實例
● 不同的作用域(serviceProvider)內創建的同一個類的對象是不同的實例
● 這種?命周期適?于需要在特定作?域內共享對象實例的情 況,?如Web應?程序中的每個HTTP請求

ServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddScoped<ITestService, TestService>();
ServiceProvider serviceProvider1 = serviceDescriptors.BuildServiceProvider();ITestService testService1 = serviceProvider1.GetService<ITestService>();
ITestService testService2 = serviceProvider1.GetService<ITestService>();
bool isflg = object.ReferenceEquals(testService1, testService2);
Console.WriteLine($"testService1==testService2   {isflg}");//trueServiceProvider serviceProvider2 = serviceDescriptors.BuildServiceProvider();
ITestService testService3 = serviceProvider2.GetService<ITestService>();
ITestService testService4 = serviceProvider2.GetService<ITestService>();
bool isflg1 = object.ReferenceEquals(microphone3, microphone4);
Console.WriteLine($"testService3==testService4   {isflg1}");//truebool isflg2 = object.ReferenceEquals(testService1, testService3);
Console.WriteLine($"microphone1==microphone3   {isflg2}");//false

3.AddTransient 瞬時生命周期

● 每一次都會創建出一個全新的實例
● 如果需要每次都創建實例—瞬時

ServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddTransient<ITestService, Microphone>();
ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
ITestService testService1 = serviceProvider.GetService<ITestService>();
ITestService testService2 = serviceProvider.GetService<ITestService>();
bool isflg = object.ReferenceEquals(testService1, testService2);
Console.WriteLine($"testService1==testService2   {isflg}"); //fals

依賴注入方式

1.構造函數注入

在執行構造函數的時候,能夠把構造函數依賴的參數自動構造出來,傳遞進來;–無限層級

public class MainViewModel
{private readonly ITestService _testService;public MainViewModel(ITestService testService){this._testService = testService;}
}

2.屬性注入

在某個類的內部包含的有屬性,在構造出整個類的時候,這個類中的某些屬性,能夠自動根據屬性的類型–自動構造出實例–賦值給屬性;
官方不支持需要引入第三方框架

public class MainViewModel
{[Inject]public ITestService TestService { get; set; }public MainViewModel(){}
}

3.方法注入

在某個類的內部,包含的有一些特殊的方法,在構造這個類的實例的時候,能夠自動的把方法執行掉,方法需要的參數—自動構建實例,傳遞進來;
? [FromServices] 需要引用 NuGet 包:Microsoft.AspNetCore.Mvc(僅限 ASP.NET Core 項目)。

public class MainViewModel
{public MainViewModel(){}public void Test([FromServices] ITestService testService){testService.GetMessage();}
}

原生WPF項目使用IOC

public partial class App : Application
{public static App CurrentApp { get; private set; } = null!;public App(){CurrentApp = this;}public IServiceProvider ServiceProvider { get; set; } = null!;protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);var serviceCollection = new ServiceCollection();ConfigureServices(serviceCollection);this.ServiceProvider = serviceCollection.BuildServiceProvider();var mainWindow = this.ServiceProvider.GetService<MainWindow>();mainWindow?.Show();}private void ConfigureServices(IServiceCollection services){services.AddSingleton<MainWindow>();services.AddSingleton<MainViewModel>();services.AddTransient<ITestService, TestService>();}
}
public partial class MainWindow : Window{public MainWindow(){InitializeComponent();this.DataContext = App.CurrentApp.ServiceProvider.GetService(typeof(MainViewModel));}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92324.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92324.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92324.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python----大模型(基于Fastapi+streamlit的機器人對話)

一、準備工作 1.1、魔搭社區下載大模型 通義千問2.5-7B-Instruct 模型庫 from modelscope.hub.snapshot_download import snapshot_download llm_model_dir snapshot_download(Qwen/Qwen2.5-7B-Instruct,cache_dirmodels) 1.2、啟動vllm大模型 python -m vllm.entrypoint…

前端面試專欄-工程化:29.微前端架構設計與實踐

&#x1f525; 歡迎來到前端面試通關指南專欄&#xff01;從js精講到框架到實戰&#xff0c;漸進系統化學習&#xff0c;堅持解鎖新技能&#xff0c;祝你輕松拿下心儀offer。 前端面試通關指南專欄主頁 前端面試專欄規劃詳情 微前端架構設計與實踐 一、微前端核心概念與價值 …

Spring Boot音樂服務器項目-上傳音樂模塊

項目結構圖 相較于上次新增集中在這些地方&#xff1a; &#x1f680; 上傳音樂的核心流程 前端投遞&#xff1a;用戶填寫歌手名 選擇MP3文件 后端接收&#xff1a;/music/upload 接口化身音樂快遞員 安全驗證&#xff1a;先查用戶是否“持證上崗”&#xff08;登錄態&#…

2025年遠程桌面軟件深度評測:ToDesk、向日葵、TeamViewer全方位對比分析

隨著遠程辦公和數字化協作的深入發展&#xff0c;遠程桌面軟件已經成為個人用戶和企業的必備工具。在2025年的今天&#xff0c;遠程控制軟件市場呈現出百花齊放的態勢&#xff0c;其中ToDesk、向日葵和TeamViewer作為市場上的三大主流選擇&#xff0c;各自在技術創新、性能優化…

深度學習-全連接神經網絡2

六、反向傳播算法 反向傳播&#xff08;Back Propagation&#xff0c;簡稱BP&#xff09;算法是用于訓練神經網絡的核心算法之一&#xff0c;它通過計算損失函數&#xff08;如均方誤差或交叉熵&#xff09;相對于每個權重參數的梯度&#xff0c;來優化神經網絡的權重。 1、前…

C語言的歷史

C 語言是一種 通用的、過程式的編程語言&#xff0c;由 丹尼斯里奇&#xff08;Dennis Ritchie&#xff09; 在 1972 年于貝爾實驗室開發。它以 高效、靈活、貼近硬件 而著稱&#xff0c;廣泛應用于系統軟件、嵌入式系統、驅動程序、游戲引擎、數據庫系統等底層開發領域。 C語…

jupyter使用

啟動win rcmdjupyter notebook創建python文件

linux 環境服務發生文件句柄泄漏導致服務不可用

問題描述&#xff1a;服務調用遠程rest接口 報錯&#xff0c;發生too many open files 異常&#xff0c;系統句柄資源耗盡&#xff0c;導致服務不可用。排查經過&#xff1a;1、針對報錯代碼進行本地構建&#xff0c;構造異常&#xff0c;并進行壓測。問題未復現2、經過討論分析…

手機錄制視頻時,硬編碼和軟編碼哪個質量高?(硬件編碼、軟件編碼)

文章目錄**1. 畫質對比**- **軟編碼**&#xff1a;- **硬編碼**&#xff1a;**2. 性能與功耗**- **軟編碼**&#xff1a;- **硬編碼**&#xff1a;**3. 實際應用中的權衡****4. 現代手機的折中方案****5. 如何選擇&#xff1f;****總結**在手機錄制視頻時&#xff0c; 軟編碼的…

IPv4與IPv6雙棧協議:網絡過渡的關鍵技術

為什么需要IPv4與IPv6共存&#xff1f; 在網絡技術的世界中&#xff0c;兼容性問題始終是最大的挑戰之一。IPv4和IPv6之間存在根本性的不兼容性&#xff0c;這意味著使用不同協議的設備無法直接通信。這種情況就像是兩個人試圖用完全不同的語言進行對話一樣。 目前的網絡現狀…

【牛客刷題】數字變換

一、題目描述 給出兩個數字a,ba,ba,b,aaa每次可以乘上一個大于1的正整數得到新的aa

MySQL 學習一 存儲結構和log

1.InnoDB邏輯存儲結構 表空間->段->區->頁->行->數據表空間&#xff1a;覆蓋了所有的數據和索引&#xff0c;系統表在系統表空間&#xff0c;還有默認表空間等 段&#xff1a;多個段組成表空間 區&#xff1a;多個區組成段&#xff0c;一般每個區的大小通常是1M…

TCP day39

六&#xff1a;C/S和B/S端 C/S&#xff1a;Client, server B/S&#xff1a;Browser server 1.cs 專用客戶端 bs 通用客戶端 2.協議不同 Cs 標準協議&#xff0c;自定義協議 Bs http 超文本傳輸 3.cs 功能復雜 bs 功能弱 4.bs 資源都在ser&#xff0c;有ser發送到cli cs 大部分資…

6 種無線傳輸照片從安卓到 Mac 的方法

將大量照片從安卓設備傳輸到電腦上&#xff0c;不僅可以備份照片&#xff0c;還能釋放設備存儲空間。雖然使用 USB 數據線可以在 Windows 電腦上輕松完成傳輸&#xff0c;但將安卓手機連接到 Mac 并非如此簡單。因此&#xff0c;許多用戶更傾向于無線傳輸照片從安卓到 Mac。您可…

在vscode 使用 remote-ssh

vscode安裝插件Remote-SSH,直接安裝即可 安裝完畢之后 在左下角有這個圖標 點擊之后選擇連接到主機然后選擇添加新鏈接之后輸入用戶名和主機地址 非默認端口使用 -p 端口號之后選擇第一個即可如果使用的是密碼,直接連接,然后輸入密碼即可如果使用的密鑰,則修改.ssh\config文件中…

RabbitMQ03——面試題

目錄 一、mq的作用和使用場景 二、mq的優點 2.1架構設計優勢 2.2功能特性優勢 2.3性能與可靠性優勢 2.4生態系統優勢 2.5對比優勢 三、mq的缺點 3.1性能與擴展性限制 3.2功能局限性 3.3運維復雜度 3.4與其他消息隊列的對比劣勢 四、mq相關產品&#xff0c;每種產品…

應用層攻防啟示錄:HTTP/HTTPS攻擊的精準攔截之道

一、七層攻擊的復雜性 # CC攻擊模擬工具&#xff08;Python實現&#xff09; import requests import threadingtarget_url "https://example.com/search?q"def cc_attack():while True:# 構造惡意搜索請求malicious_query "0" * 1000 # 長查詢參數try…

.net 警告【代碼 CS1998】此異步方法缺少 “await“ 運算符,將以同步方式運行。

【代碼 CS1998】此異步方法缺少 “await” 運算符&#xff0c;將以同步方式運行。請考慮使用 “await” 運算符等待非阻止的 API 調用&#xff0c;或者使用 “await Task.Run(…)” 在后臺線程上執行占用大量 CPU 的工作。在 VS 2022 中遇到的 CS1998 編譯器警告&#xff0c;表…

【自動駕駛黑科技】基于Frenet坐標系的車道變換軌跡規劃系統實現(附完整代碼)

1. 代碼結構概覽該代碼實現了一個車道變換軌跡規劃系統&#xff0c;包含兩個核心模塊&#xff1a;道路建模&#xff08;EnhancedRoadModel&#xff09;&#xff1a;基于樣條曲線構建道路模型。軌跡規劃&#xff08;LaneChangePlanner&#xff09;&#xff1a;根據障礙物狀態和道…

uni-calendar自定義簽到打卡顏色

uni-calendar自定義簽到打卡顏色&#xff0c;只需要將打卡的狀態添加到動態類class中即可 效果&#xff1a;在uni-modules >>> components >>> uni-calendar >>> uni-calendar-item.vue文件中&#xff0c;根據info對應的文字或者符號添加不同的clas…