IOC 容器 DI 依赖注入 是什么? 为什么有这个东西?要怎么用? 先看个图 然后下面说明
IOC 控制反转 因为懒不想自己搞 DI 依赖注入 依赖抽象 注入就是实列化
目的: 对象的创建 和销毁
好处:可以无限递归,依赖
(图片来自网络)
传统的做法
1:实列化一个 对象的时候 都是 new 一个class A 如果说 之后 要改名字的话 需要找到所有 实列化的地方 去改名字
2:在构造函数的时候 如果有继承层级关系 比如 A-B-C-D 那么构造函数需要构造4次
由于这些主动改起来过于难受 于是引发思考,有没有一个可以帮助去操作这些对象实列(也即是细节)的东西?
这个东西 就是 IOC 容器 (第三方操作者) IOC 的含义就是控制反转 就是 把控制权不是由自己去动手主动操作了 变动交予别人帮忙
可以理解为 拿钱买东西 以前自己去买 现在 把钱给 IOC容器 第三方 然后帮我把东西买回来
那有这么个IOC容器帮我们做事情,是我们所想要的 最终目的
那怎么实现这个,给了钱 如何帮我把东西买回来? 这就是 DI 依赖注入 实现手段
怎么就能实现手段? 肯定不是说一下就实现了,必定有实现的原理和相关流程操作。
依赖注入 其实是Core 里面的 扩展类 需要引入nuget包 Microsoft.Extensions.DependencyIn 这样你就会发现 依赖注入 这门手艺 不止一处 也可以使用第三方插件的 nuget包,autofac 等等
这样也说明了 依赖注入 这门手艺 这个手段 也是很常见使用的
依赖注入(流程操作): 抽象-实现-注册-使用 也就是能够达到目的 核心的理念 实现的过程
1 抽象 对细节的依赖转变成对抽象的依赖 这样解决了 第一个问题 类名变了之后 需要手动多处的改名字 就 变成了 对 抽象的一个地方的更改 也就是图片上IBLL 与 IDAL
2 实现 也就是实例化的操作 并且 可以递归 去实现 这样就解决了 第二个问题 手动去多次构造函数
3 注册 实现之前需要知道要实现什么东西吧 ( 注册) 也就是ioc容器注册服务 需要在 startup类里面进行说明
4 使用 那就是框架根据你注册的东西 调用构造函数进行了实列化
一个服务是一个抽象 对应一个实现
但是如果说 就要一个抽象对应多个实现 比如 抽象 车这个类 多个实现 有 火车 汽车 卡车等等
正常的理念来讲 就是 每个类型的车应该建立 对应的实现 汽车对应汽车抽象 火车对应火车抽象 直接去注册就行了
但是如果就是一个抽象 要多个实现 帮我注册 那肯定要配置 说明到底 是注册 汽车 还是 火车 那么这需要去配置服务
要注意 如果你 汽车 火车都想注册 那这种就不可行了 毕竟 一个抽象 框架只会帮你实现一个 你即便是多个实现 无非是配置 一下告诉框架 选择一个去实现 这种场景只适用于 汽车 火车 我只需要一个实现,能配置切换罢了
以下 是举例说明 发送信息 服务 自定义配置 是发邮件还是发短信 了解以下 配置服务的写法 如何封装 即可
正常注册:
1直接 在配置服务中 addsingleton<抽象,实现>
2配置的话 首先把这个 addsingleton<抽象,实现> 先封装到 扩展构建类中 然后方法 UseEmail() UseSms() 中去
3 因为要扩展构建类 调用UseEmail() UseSms() 其中的一个 需要一个配置项 去选择哪一个 所以在进行封装
再扩展以下把这一步放到注册服务时 调用选择 创建注册服务时的 方法名字 AddMessage() 在里面的参数有 服务提供对象 以及 扩展构建的类
思路就是 1 先把 注册方法 封装到 构建服务扩展类 2. 封装调用 服务扩展的 调用服务扩展类
构建扩展 使用服务集合去调用核心方法 调用扩展 需要 构建者去使用服务 这样 在 注册的时候 就配置了
注意:全程IOC 使用 不能 使用了IOC 注册了 class A 在去new class A 实列化对象 那么IOC是会不起作用的