.net core 依赖注入生命周期 Singleton、Scoped、Transient
1.控制反转与依赖注入
我们在学习依赖注入生命周期之前,先了解一下依赖注入控制反转,控制反转IoC(Inversion of Control)是一种思想,依赖注入DI(Dependency Injection)是控制反转的一种实现,通过Ioc容器把原来开发人员主动创建对象等工作,交给了容器进行创建与管理,实现了控制的反转。可以降低代码直接的耦合度,实现解耦
2.三种模式的生命周期
Singleton 单一实例模式:在首次请求时创建,创建后,每一个后续请求都使用同一个实例,单一实例服务必须是线程安全的,并且通常在无状态服务中使用。
Scoped 作用域模式:作用域对象在一个客户端请求中是相同的,但在多个客户端请求中是不同的
Transient 暂时模式:每次请求时都会创建新的实例,无论是不是同一个请求,同一个客户端
微软官方文档:https://docs.microsoft.com/zh-cn/dotnet/core/extensions/dependency-injection#service-lifetimes
3.Singleton,Transient,Scoped 基本用法
首先每种注册方式都增加一个接口和实现类
每个实现类里面包含以下内容,以便在接下来了解三种注册方式的生命周期。
在Startup类中的ConfigureServices 方法中注册服务
服务注入方式有属性注入,构造函数注入等,我们通过构造函数注入的方式注入已经注册的服务。这里我们每个服务注入两次,以便清楚的了解在每次请求时,每种注册方式的实例的情况
通过调用两次接口,得出以下所示结果。单例模式下,每次请求都是一样的,作用域模式下,一个请求的生命周期内是一样的,瞬时模式下,每次服务请求都不一样。
4.使用场景
AddSingleton: 将单例对象添加到应用程序中,该对象在整个应用程序生命周期中只有一个实例。首先,使用 AddSingleton 可以有效减少内存占用,因为该服务只需要被创建一次,并且应用程序中的其他部分都可以共享同一个实例。其次,由于单例是全局唯一的,这就使得在应用程序启动时配置一些服务非常方便,而这些服务也不需要在应用程序的生命周期内频繁地创建和释放,例如配置数据库连接、身份验证等服务。
AddScoped: 将作用域对象添加到应用程序中,该对象的生命周期与请求的作用域一致,一旦请求结束,对象将被销毁。这种方式适用于需要在请求期间处理共享状态的服务。例如请求中可能会使用一个数据库上下文来处理数据库相关操作,这时候使用 AddScoped 就可以保证数据库上下文的实例在请求期间是唯一的,从而避免了多个请求之间的冲突和数据错乱。
AddTransient: 将瞬态对象添加到应用程序中,每次服务请求都会创建一个新的实例。适用于需要经常创建和销毁的轻型服务。例如,使用 AddTransient 注册日志记录服务可以保证每次日志记录都会创建一个新的实例,从而可以避免在多个请求中共享相同的日志记录器实例导致的数据混乱。