C# 深入理解IOC

目录

为什么要用IOC

IOC的实现原理

IOC(控制反转)

DI(依赖注入)

IOC生命周期

ServiceCollection/ServiceProvider

Scrutor

IOC单接口多实例

构造函数注入优势

为什么要用IOC

  1. 为什么要用IOC呢?
  2. Controller调用BLL,BLL调用DAL,再写个DBHelper的类,DAL在调用DBHelper里面的方法,项目不 也照样做的飞起吗?
  3. 这种做法其实最核心的思想就是职责分离,一个DAL对象可以被多个BLL对象使用,一个BLL对象也 可以被多个Controller对象使用。
  4. 这种做法有一个比较大的问题,那就是目前只做到了逻辑的复用,但是并没有做到资源的复用。
  5. 本来应该多个Controller对象共用一个BLL对象,多个BLL对象又共用一个DAL对象。
  6. 现在变成了一个Controller对象创建了多个重复的BLL对象,然后多个BLL对象又创建了多个重复的 DAL对象。
  7. 问题就是很多对象其实只需要创建一次就够了,创建那么多也没有什么意义。
  1. 所以针对对象重复创建的问题,可以用单例模式来解决。
  2. 单例模式要确保整个应用程序中有且仅有一个实例,对象只能被创建一次。
  1. 所以用单例模式创建的对象必须是该单例类私有的静态对象。
  2. 问题就是它是静态对象,静态对象会被存储在”静态存储区”里面,一直到程序退出,才会被回收。
  3. 那也就意味着通过单例模式创建的对象越多,内存占用的也就越多。
  4. 那有些小公司也不在乎这点内存,项目就这么大,占不了多少内存,占这点内存无所谓,不够了再加。
  5. 那还有一个问题,就是后面我觉得这个BLL对象起的名字不妥,想改一下,那所有用到这个BLL对象 的Contoller对象都得改。
  6. 那有些人说了,那我不改不就行了,项目能跑能用就行,命名没有那么严格。
  7. 那还有一个问题,如果说现在new一个简单的对象,那没啥问题。如果现在new的这个对象比较复杂, 在创建的时候还需要先new其它对象。其它对象在new的时候也比较复杂,比如构造函数里面需要传 入很多参数,new完还要给很多的属性赋值。刚好需要传入的参数还有需要进行赋值的属性都是一些 配置性的东西,会随着业务的需求不断的在变。那这个时候,你就得需要修改每一个用到了该对象的 地方,项目越大,业务越复杂,改的就越多。
  8. 所以就需要IOC容器来创建对象,进行解耦,把对象之间的这种依赖关系交给IOC容器来处理,就完 事了。
  9. 但是一些小公司,做的一些小项目,需求也没那么复杂,也就没有必要用IOC。

IOC的实现原理

  1. 根据传入的泛型类型,获取它的Type类型对象。
  2. 根据Type类型的对象,调用GetConstructors方法获取它的构造函数,是一个ConstructorInfo数组。
  3. 然后进行构造函数的筛选,找出有构造函数参数的ConstructorInfo对象。
  4. 然后调用ConstructorInfo对象的GetParameters方法,获取全部的构造函数参数,是一个ParameterInfo 类型的数组。
  5. 然后对这个ParameterInfo类型的数组进行遍历,调用每个ParameterInfo对象的ParameterType属性来 获取ParameterInfo对象的Type类型对象,把它放到一个List集合里面保存起来。
  6. 最后调用Activator对象的CreateInstance方法创建对象,CreateInsatance方法的第一个参数就是传入 的泛型类型的Type类型对象,第二个参数就是存放ParameterInfo对象的Type类型对象的集合,但是 得调用ToArray方法把它转成数组。
  7. 大概就是这么一个思路,更具体的细节现在也记不住了。

IOC(控制反转)

  1. IOC的思想就是把对象之间的依赖关系交给容器来处理,上层不再依赖于下层,而是依赖于抽象,IOC 容器来实例化下层。
  2. 所以IOC它就是一种目标,让程序解耦,让第三方的IOC容器来创建对象,DI是实现IOC的手段。
  3. IOC也可以理解为一个实例化对象的工厂,它的这种思想也符合设计模式中的依赖倒置原则。

DI(依赖注入)

  1. DI就是依赖注入。
  2. 依赖注入就是构造A对象的时候发现先需要构造B对象,那么先构造B对象然后再构造A对象。
  3. 就是让对象能够自动的进行注入。

IOC生命周期

  1. IOC的生命周期主要有三种。
  2. 第一种是瞬时,AddTransient,服务随时创建随时销毁。
  3. 第二种是单例,AddSingleton,从程序启动开始到程序被终止为止,服务永远只构造一次。
  4. 第三种是作用域单例,AddScoped,服务在这一次请求中,只构造一次。

ServiceCollection/ServiceProvider

  1. 在.NetCore中关于IOC有两个重要的对象。
  2. 第一个是ServiceCollection对象,它只支持构造函数的注入,用来添加服务,是一个用来存放服务注册 信息的集合。
  3. 第二个是ServiceProvider对象,它是用来获取IOC容器的实例,可以调用ServiceCollection对象的 BuildServiceProvider方法创建ServiceProvider对象。

Scrutor

  1. 在.NetCore中可以通过Scrutor来简化DI服务的注入方式,因为如果服务太多的话,去Add添加服务 很容易出错。
  2. Scrutor它不是依赖注入框架,而是.NetCore内置的DI扩展包。
  3. 可以根据一些约定来进行DI服务的自动注册,比如以Service结尾的服务,就可以进行自动注入,不 需要每个手动都去Add添加。

IOC单接口多实例

定义集合类型获取所有实例。

 

构造函数注入优势

  1. 通过构造函数的方式注入对象,可以声明为readonly,动态常量,保证对象的不可变性。
  2. 可以保证依赖不为空,因为readonly声明的对象必须在声明时初始化或者在构造函数执行时初始化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子丶鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值