依赖注入DI与控制反转IOC核心解析

依赖注入 DI

控制反转 IOC

A 依赖B,就A只用B,但对B怎么产生与销毁不管

讨论下:A如何可以用到B?

1)当作参数传给A,可以利用构造函数传,当然也可以当作方法参数传

2)B是A的属性,赋值传入即可

不用每次在用的时候传进去,A想用B的时候 直接用就行

IOC Container出来了

OK,既然A不用管B的生成与销毁,那么IoC 容器 怎么实现 B的生成与销毁,还有如何将B传给A了?

IOC容器流程如下:

依赖注入DI与控制反转IOC核心解析

注册服务:告诉容器规则,这个接口最终用哪个实现体,就是服务与实现的映射表,AddScoped<IServiceB, ServiceB>()时,容器就记录下了一条规则:“有人要 IServiceB?好的,那我就创建一个 ServiceB的实例给他
解析与注入:当你的应用程序运行时,框架(如 ASP.NET Core)需要创建某个对象(例如一个控制器 MyController,也就是对象 A)时,会发生以下自动化的神奇步骤:
  • 发现依赖:框架发现 MyController的构造函数需要一个 IServiceB类型的参数
  • 递归解析:容器(IServiceProvider)接到指令后,会查看自己内部的注册表。它发现 IServiceB对应 ServiceB。于是,它开始动手创建 ServiceB的实例。关键点:如果 ServiceB本身也有依赖(比如它需要 IServiceC),那么容器会递归地重复这个过程:先解析 IServiceC的实例,然后将其注入到 ServiceB中,最后完成 ServiceB的创建。这个过程会构建出一完整的“对象依赖树” 。
  • 完成注入:容器将创建好的 ServiceB实例(也就是对象 B)传递给 MyController的构造函数。至此,依赖注入完成

生命周期管理:容器如何“销毁”对象

对象的销毁方式完全取决于其注册时指定的生命周期。.NET Core 内置了三种主要生命周期 :

生命周期 注册方法 对象创建与销毁时机
瞬时 AddTransient 每次请求都会得到一个新实例。容器不负责销毁,由 .NET 的垃圾回收器在对象不再被使用时自动回收。
作用域 AddScoped 每次网络请求(或一个自定义的作用域内)共享同一个实例。当请求结束时,容器会释放(Dispose)那些实现了 IDisposable接口的实例。这是管理数据库连接等资源的关键机制。
单例 AddSingleton 整个应用程序生命周期内只有一个实例。容器会一直持有该实例,直到应用程序关闭时才会将其释放。

所以,对于 B 的销毁:

  • 不需要也不能手动 newdelete(销毁)。
  • 容器的责任就是根据上述规则,在正确的时机(特别是对于 ScopedSingleton服务)调用它们的 Dispose()方法以释放资源(如数据库连接、文件句柄)。

💡 核心价值总结

通过这套机制,.NET Core 的 IoC 容器实现了:

  1. 控制反转:将对象的创建权从业务代码反转到容器。
  2. 依赖注入:由容器负责将依赖项注入到需要它的对象中。
  3. 解耦MyController只依赖于抽象 IServiceB,而不关心具体的实现是谁,更不关心它如何创建和销毁。这使得代码更容易测试(测试时可以注入一个模拟实现)和维护 。

转载请注明:深圳彦祖 » 依赖注入DI与控制反转IOC核心解析

喜欢 (0)

您必须 登录 才能发表评论!

粤ICP备17031696号-1