控制反转
传统开发中,对象都是开发者创建组装,开发者必须了解各类的使用方法且某些类的耦合度较高,例如想把sql serve数据库改为MySql数据库则需要更改某些代码。
控制反转的目的是让框架完成对象的创建和组装。从“我创建对象”编程“我要对象”
依赖注入
控制反转(inversion of control,IOC)是设计模式中非常重要的思想,而依赖注入(dependency injection,DI)是控制反转思想的一种重要的实现方式。依赖注入简化了模块的组装过程,减小了模块之间的耦合度,因此.NET Core中大量应用了依赖注入的开发模式
实现控制反转主要有两种方式:
1:服务定位器
2:依赖注入
服务
注册到容器中的对象(依赖项注入术语中,服务通常是指向其他对象提供服务的对象,既可以作为其他类的依赖项,也可能依赖于其他服务。服务是 Ioc 容器管理的对象。)
服务生命周期
使用了依赖注入框架之后,所有我们注入到容器中的类型的创建、销毁工作都由容器来完成,那么容器什么时候创建一个类型实例,什么时候销毁一个类型实例呢?这就涉及到注入服务的生命周期了。根据我们的需要,我们可以向容器中注册服务的时候,对服务的生命周期进行设置。服务的生命周期有以下三种:
(1) 单例 Singleton
注册成单例模式的服务,整个应用程序生命周期以内只创建一个实例。在应用内第一个使用到该服务时创建,在应用程序停止时销毁。
在某些情况下,对于某些特殊的类,我们需要注册成单例模式,这可以减少实例初始化的消耗,还能实现跨 Service 事务的功能。
(2)范围(或者作用域) Scoped
在同一个范围内只初始化一个实例 。在 web 应用中,可以理解为每一个 request 级别只创建一个实例,同一个 http request 会在一个 scope 内。
(3)多例 Tranisent(也叫瞬态)
每一次使用到服务时都会创建一个新的实例,每一次对该依赖的获取都是一个新实例。
使用建议:
如果一个类无状态,建议设置为单例;否则,框架环境有范围控制,则周期设置为范围;使用瞬态周期时要尽可能在自范围中使用,否则容易造成内存泄漏。
不同服务之间具有依赖关系,A服务有一个B服务的属性,那么B的声明周期不能比A短
依赖注入框架中注册服务的时候,可以设定服务类型和实现类型,这两者可以不相同。
例:
服务类型和实现类型都是SqlConnection时,在获取SqlConnection服务时,会返回SqlConnection对象
服务类型是IDbConnection接口类型,实现类型都是SqlConnection时,在获取IDbConnection接口服务时,会返回SqlConnection对象
如何使用依赖注入