C#摸鱼实录——IoC与DI案例详解
IoC(控制反转)与DI(依赖注入)
开一个新的模块哈,在这个模块里面,我们主要讲一个东西如何使用,尽量不纠结概念,简单过过
之前老是被人说,是不是过于偏向于学院派了,所以从现在开始,我们将只关注能不能用
这个模块里面,我想讲的,大多数是在实际项目中常用的东西,例如一些NuGet 包,一个语法,或者某种设计模式
不过不过多描述概念了,不讲官方那些罗里吧嗦的概念,只需要理解他是什么鬼东西,干什么的,怎么用即可
大抵就是学院派和江湖派的区别吧
顺便后面我要是忘记这个东西怎么用了,还可以回来看看文档,顺便,这就是我未来AI的蒸馏对象我蒸馏我自己
然后,为什么要进行这么古老的学习方式,废话,这年头AI快把初级员工的路堵死了,
不来点古法编程,抽象能力提升很慢的,用了AI几个月,发现初级迈向中级,你不古法编程就等死吧
而且上班摸鱼时间一大把,系统性的学习学习怎么了,打发时间也挺好的,然后深入学习一下IoC的思想
废话少说,进入正题
一.DI依赖注入 — 概念
[!TIP]
如果你不想看文字,或者觉得我这一块讲的不是特别明白的,想看视频教学的话
推荐一位up做的关于依赖注入的教学视频,大概30分钟左右的教学,
只不过后面几个视频初学者容易看不懂
【.Net-依赖注入】从依赖说起_哔哩哔哩_bilibili
很多人可能经常使用依赖注入,但是不知道他叫什么,DI是什么鬼东西,其实看一眼代码就了解了不懂你就再看一眼
1.什么是依赖(Dependency)?
一个对象要工作,需要另一个对象的帮助,没有另一个对象就完成不了
/// 因为产品需要零件A,所以产品依赖于零件A /// 即:零件A就是产品的依赖 public class 零件A { public int GetID() => 100; } public class 产品 { private readonly 零件A _a; public 产品(零件A a) => _a = a; }
2.什么是注入(Injection)?
把对象交给另一个对象使用
// 通过对象product使用了对象a var a = new 零件A(); var product = new 产品(a);
3.什么是依赖注入(Dependency Injection)?
依赖注入 = 依赖 + 注入
- 即:对象所需要的依赖由外部提供,而不是自己创建
下面是依赖注入的一点基本概念,结合上面的内容,已经写的非常清楚了,就不再过多阐述
// 一个用于示例的空类DbService public interface IDbService { void Insert(); } public class DbService : IDbService { public DbService() { } public void Insert() => Console.WriteLine("====================================="); } /// <summary> /// 传统写法 - 不使用依赖注入(模块之间强依赖,耦合度高) /// </summary> public class NO_DI { // 🌱钱没给够,你自己new吧 private DbService _db = new DbService(); public void Save() => _db.Insert(); } /// <summary> /// 使用依赖注入(松散解耦) /// </summary> public class Yes_DI { private readonly DbService _db; // 🌱钱给够了,直接从外部“注入” public Yes_DI(DbService db) => _db = db; public void Save() => _db.Insert(); } /// <summary> /// 依赖注入常用三种方式(但是基本上还是以构造注入为主) /// </summary> /// <summary> /// 1.1构造注入 /// </summary> public class 构造注入 { private readonly DbService _db; public 构造注入(DbService db) => _db = db; // var a = new A(); // var demo = new 构造注入(a); } /// <summary> /// 1.2.属性注入 /// </summary> public class 属性注入 { public 属性注入() { } public DbService DB { get; set; } = null!; // 属性注入 demo = new 属性注入(); // demo.DB = new DbService(); } /// <summary> /// 1.3.方法注入 /// </summary> public class 方法注入 { public 方法注入() { } public void Execute(DbService db) { } // 方法注入.Execute(new DbService()); }
二.IoC(控制反转)— 概念
1.什么是控制(Control)?
谁决定对象如何产生和使用
- 控制权:决定某件事情如何进行的权力
- 在IoC中,特指:创建什么对象,什么时候创建,对象如何创建对象的决定权
- 看不懂就看下面的例子,一眼秒懂
- 控制权:决定某件事情如何进行的权力
// 产品控制着零件A的创建 // 即:产品拥有创建零件A的控制权 // 缺点,产品和零件A已经绑死了,高度耦合,扩展等死,后人挠头,直骂屎山 public class 零件A { } public class 产品 { private readonly 零件A _a; public 产品() { _a = new 零件A(); } }
2.什么是反转(Inversion)?
反转 = 原来的方向反过来了
- 原本由A负责的事情,改由B负责
在IoC中通常指:控制权发生变化,由内部控制变成外部控制
public class 零件A { } //======================================= // 内部控制 public class 产品 { private readonly 零件A _a; public 产品() { _a = new 零件A(); } } //======================================= // 外部控制 public class 产品 { private readonly 零件A _a; public 产品(零件A a) { _a = a; } }
3.什么是控制反转(Inversion of Control)?
控制方向被反过来了,所以叫控制反转控制反转:原本由对象自己掌握的控制权,转移给了外部对象或容器
- 但是需要注意的是,IoC是一种思想,它并不是某种具体的实现
- 换句话说,DI是IoC的一种实现方式,依赖注入就是使用控制反转的思想
- 即:依赖注入(DI)是实现IoC最常见的方式之一
# 原来:产品内部控制零件A 产品 ↓ # 控制 零件A #==================================================