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…