.NET CORE DI 依赖注入DI几个概念服务(service):对象;注册服务;服务容器:负责管理注册的服务;查询服务:创建对象及关联对象;对象生命周期:Transient(瞬态);Scoped(范围);Singleton(单例)1. .NET中使用DI(1)1....
.NET CORE DI 依赖注入
DI几个概念
服务(service):对象;
注册服务;
服务容器:负责管理注册的服务;
查询服务:创建对象及关联对象;
对象生命周期:Transient(瞬态);Scoped(范围);Singleton(单例)
1. .NET中使用DI(1)
1.测试代码见备注
2.根据类型来获取和注册服务
可以分别指定服务类型(service type)和实现类型(implementation type).这两者可能相同,也可能不同.服务类型可以是类,也可以是接口,建议面向接口编程,更灵活.
3…NET控制反转组件取名为DependencyInjection,但他包含ServiceLocator的功能
2. .NET中使用DI(2)
1.Install-Package
Microsoft.Extensions.DependencyInjection
2.using Microsoft.Extensions.DependencyInjection
3.ServiceCollection用来构造容器对象
IServiceProvider.调用ServiceCollection的BuildServiceProvider()创建的ServiceProvider,可以用来获取BuildServiceProvider()之前ServiceCollection中的对象
问题:源 Microsoft Visual Studio Offline Packages 中不存在具有此 ID 的
解决:
一、工具-->Nuget程序包管理器-->程序包管理器设置
二、 Nuget Package Manager-->程序包源
三、点击右上角的 加号按钮 ,添加一个新的Nuget源选项
四、名称:随便取
源:https://api.nuget.org/v3/index.json
点击右侧的 更新 按钮
如果有原包源勾掉禁用,没有忽视
重新生成解决方案,下载可能需要点时间等会就行
实例代码如下:
3.生命周期
1.给类构造函数中打印,看看不同生命周期的对象创建,使用ServiceProvider.CreateScope()创建Scpoe
2.如果一个类实现了IDisposable接口,则离开作用域之后容器会自动调用对象的Dispose方法
3.不要在长生命周期的对象中引用比它短的生命周期的对象.在ASP.NET Core中,这样做默认会抛异常.
4.生命周期的选择:如果类无状态,建议为Singleton;如果类有状态,且有Scope控制,建议为Scoped,因为通常这种Scope控制下的代码都是运行在同一个线程中的,没有并发修改的问题;在使用Transient的时候要谨慎
5…NET注册服务的重载方法很多
4.IServiceProvider的服务定位器方法:
1.T GetService() 如果获取不到对象,则返回null
- Obeject GetService(Type serviceType)
2.T GetRequiredService() 如果获取不到对象,则抛异常
- Object GetRequiredService(Type serviceType)
3.IEnumerable GetService() 适用可能有很多满足条件的服务
- IEnumerable GetService(Type ServiceType)
5.真正开始依赖注入
1.依赖注入是有"传染性"的,如果一个类的对象是通过DI创建的,那么这个类的构造函数中生命的所有服务类型的参数都会被DI赋值;但是如果一个对象是程序员手动创建的,那么这个对象就和DI没有关系,它的构造函数中生命的服务类型参数就不会被自动赋值.
2…NET的DI默认是构造函数注入
3.举例:编写一个类,连接数据库做插入操作,并且记录日志(模拟的输出),把Dao,日志都放入单独的服务类
6.原理复刻
需求说明
1.有配置服务,日志服务,然后再开发一个邮件发送器服务.可以通过配置服务来从文件,环境变量,数据库等地方读取配置,可以通过日志服务来将程序运行过程中的日志信息写入文件,控制台,数据库等
2.说明:案例中开发了自己的日志,配置等接口,这只是在揭示原理,.NET有现成的
实现1
1.创建三个.NET Core类库项目,ConfigServices是配置服务的项目
LogServices是日志服务的项目
MailServices是邮件发送器的项目
然后再建一个.NET Core控制台项目引用ConfigServices项目和LogServices项目,而MailServicesConsole项目引用MailServices项目.
2.编写类库项目LogServices,创建ILogProvider接口.编写实现类ConsoleLogProvider.编写一个ConsoleLogProviderExtensions定义扩展方法AddConsoleLog,namespace和IServiceCollection一致