首先我们要记住一个概念:依赖注入(DI)是控制反转(IOC)的实现方式。
Ioc就是将实例化的任务交给容器去做。
下面将举一个例子来演示DI的用法:
一、最原始的开发方式
首先我们建一个控制台应用(.NET),这里演示的框架我用的是.NET 6.0,演示其原理的时候其他版本的.NET框架也可以用,没有影响,我们来体会下我们最原始的开发方式
![](https://i-blog.csdnimg.cn/blog_migrate/390b8edd60030b7ce935db4c48be4f6f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7d791781a7553c755b5844c025eb61b2.png)
创建一个接口B,里面定义一个没有返回值的方法,添加一个类B用于实现接口B
![](https://i-blog.csdnimg.cn/blog_migrate/ef9247bd0f424aae24fed64a86e597d0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f8f5072a7834523e11bcff8b235b56de.png)
创建一个接口A,里面定义一个没有返回值的方法,添加一个类A用于实现接口A,并在A类方法中调用B类的方法。
![](https://i-blog.csdnimg.cn/blog_migrate/a306143852f530cafd979f51117ce10e.png)
4.在主函数中调用类A的方法
![](https://i-blog.csdnimg.cn/blog_migrate/1c2d81218eff4905c5c67ec19da613b2.png)
5.最后实现的结果为
![](https://i-blog.csdnimg.cn/blog_migrate/2ef58ec1a1651a97af8f1117b5cd7474.png)
可以看到,这种直接在需要用到的地方直接声明去使用,看似简单,却有很大的缺陷,会造成耦合性很高,如果在开发大的项目时,需要对源码做出修改,就会改很多的地方,会造成工作量巨大,这个时候如果我们换一种方式,把创建对象的方法交给另外的东西去做,就会降低类之间的耦合性,所以我们就要使用到控制反转(Ioc)这种思想。
二、使用容器来创建对象
1.首先添加一个容器类Container,在类中写入注册服务和创建实例的方法
![](https://i-blog.csdnimg.cn/blog_migrate/843962af98a4e43974704024af881176.png)
2.在需要声明对象的对象,进行注入实例
![](https://i-blog.csdnimg.cn/blog_migrate/365f719ba4473f99088df6485b1415d2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0bcc41bf6ca4feab7053271e3d7699ba.png)
结果同上面的结果相同,这就是依赖注入的基本实现原理,接下来我们将使用MVC来进行依赖注入的演示
三、使用MVC方式进行依赖注入的演示
1.首先我们新建一个MVC项目,框架使用的.NET 6.0,不同的VS版本创建项目时显示的项目名称可能不同,只要注意看项目的简介和我下面的图片一样就行
![](https://i-blog.csdnimg.cn/blog_migrate/71a3a26f9ea5743342fb0acc643e0b02.png)
在这个界面最好勾选不使用顶级语句,因为如果不勾选如果没学过顶级语句会让你感到疑惑,就按照下面图片进行勾选就好,然后点击创建
![](https://i-blog.csdnimg.cn/blog_migrate/f36bf357877f36a90018eb1454be4bc2.png)
2.然后创建一个类库,注意我下面选择类型,然后点击下一步进行
![](https://i-blog.csdnimg.cn/blog_migrate/e0f7bb8ec0db5a506fc560c95be62011.png)
在类库中添加一个UserInfo类,添加几个属性,这里只是为了演示,所以我就不加太多属性了
![](https://i-blog.csdnimg.cn/blog_migrate/fdaeb31d225257977d8d0a431477c9c1.png)
5.然后给MVC项目添加类库的引用
6.自己在控制器中创建一个登录的Action,然后创建一个是如,视图中只要有个表单提交就行,这里主要演示注入的方法,所以便不再去演示怎么去创建表单了,我这里写好了一个方法,大家也可以参考一下
![](https://i-blog.csdnimg.cn/blog_migrate/5955eae8b189d105a8a3343a9ad4f879.png)
7.然后我们再添加一个类库,在类库中添加一个接口和一个实现该接口的类,在接口中定义
一个返回值为bool类型的保存用户信息的方法
![](https://i-blog.csdnimg.cn/blog_migrate/75e8264b4d71ddbb2d47439bdcea7a2e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d61c5fcb6176f2230f4106c0c2195da1.png)
不使用依赖注入的实现方式
![](https://i-blog.csdnimg.cn/blog_migrate/ccb7f805558561df8e6d750ccc3e0c6d.png)
8.使用依赖注入前我们需要去MVC项目中的Program.cs文件中去手动进行注册服务(如果是.NET 6.0以前的版本是需要在StartUp.cs文件夹中去进行注册,如果不知道怎么注册的话,可以评论区或者私信问我),这里主要演示.NET 6.0的注册
注册时我们需要理解一个重要的概念叫做“生命周期”(具体含义可以去看看官方文档),依赖注入框架服务的生命周期有三种
瞬态(Transient):每次被请求的时候都会创建一个新对象
![](https://i-blog.csdnimg.cn/blog_migrate/e19ac13c67bf426e27e099b010ea1095.png)
范围(Scoped):在给定范围内,多次请求共享同一个服务对象,服务每次被请求的时候都会返回同一个对象;在不同的范围内,服务每次被请求的时候会返回不同的对象。
![](https://i-blog.csdnimg.cn/blog_migrate/484c11c5d6a3cfdbc0f742a3ccc90327.png)
单例(Singleton):全局共享同一个服务对象
![](https://i-blog.csdnimg.cn/blog_migrate/21b74df5eadfb58e7dc5c4d7759b9a8a.png)
9.下面我们开始需要使用DI的地方进行演示
构造函数注入
![](https://i-blog.csdnimg.cn/blog_migrate/41479ff413c895f13e30dcf7703e8031.png)
使用操作注入 [FromServices]:使用这种方式注入,就不需要在构造函数进行赋值,需要注意的是,只有ASP.NET Core控制类的操作方法才能用[FromServices]注入服务,普通的类是不行的
![](https://i-blog.csdnimg.cn/blog_migrate/eaa2017475d9ae3c908263fdb60e980b.png)
通过HttpContext直接获取需要实现的服务
![](https://i-blog.csdnimg.cn/blog_migrate/f3e669fe9deaa9bfd323099eec6c2758.png)
以上就是控制反转(Ioc)的简单介绍和依赖注入(DI)的三种注入方式的简单使用,后面我将结合一些简单的项目进行更多的依赖注入使用的介绍,写的较为潦草,理解的可能也不是很到位,请各位.NET大佬批评指正!!!