hello,大家好,今天依然是橙子老哥的分享时间,希望大家一起学习,一起进步。
欢迎加入.net意社区,第一时间了解我们的动态
官方地址:https://ccnetcore.com
微信公众号:搜索 意.Net
添加橙子老哥微信:chegnzilaoge520
最近有小伙伴问我,依赖注入天天用,无非就是构造函数递归找构造函数,这有什么难的?可是真正问到细节,却又一知半解,做一个成熟稳定的IOC真的很不容易,需要考虑并发、循环依赖、缓存、泛型、作用域等等因素
今天我们就来看看.NetCore内置的IOC容器,具体源码细节是如何实现的?由于IOC的篇幅较长,橙子老哥带大家从外层一层一层揭开依赖注入的面纱
1、使用
我们需要先安装:Microsoft.Extensions.DependencyInjection
包,默认是带了抽象包,没有实现,我们是执行不了BuildServiceProvider
的扩展方法的
以下是控制台使用,我们讲IService加入到容器,并在build之后,在从容器中获取出来
using Microsoft.Extensions.DependencyInjection;
var services=new ServiceCollection();
services.AddTransient<IService,MyService>();
var serviceProvider=services.BuildServiceProvider();
var my=serviceProvider.GetRequiredService<IService>();
my.DoWork();
public interface IService
{
void DoWork();
}
public class MyService : IService
{
public void DoWork()
{
// 实现功能
Console.WriteLine("你好");
}
}
以上的使用代码,相信大家早已经了如指掌,同样我这里没必要讲那些基础使用以及概念了
为什么要使用IOC,IOC的生命周期,IOC的好处。。。。。 这些留给大家仔细思考吧~
上面的示例的流程,我们分为三步
- services.AddTransient<IService,MyService>(); 将服务添加进服务容器中
- BuildServiceProvider 构建容器
- 通过GetRequiredService从容器中获取到对应的服务
services.AddTransient<IService,MyService>()
往里面看看
ServiceDescriptor serviceDescriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
collection.Add(serviceDescriptor);
这3步主要是用到了3个核心对象
- ServiceCollection (服务容器,我们的向容器中添加的服务存储在这里)
- ServiceDescriptor (服务描述者,我们向容器中新增的东西会转换成这个)
- ServiceProvider(服务提供者,通过服务容器构建之后,我们从这里获取对应的服务)
弄清楚了这个,我们再往里面看
2、ServiceCollection 服务容器
我们看看,这个服务容器里面是如何存储我们新增进去的ServiceDescriptor
public interface IServiceCollection : IList<ServiceDescriptor>,
ICollection<ServiceDescriptor>,
IEnumerable<ServiceDescriptor>,
IEnumerable
{
}
emmm,好像就是一个ServiceDescriptor
集合,所以通过扩展方法包几层,ServiceDescriptor
通过集合的add方法就新增进去了
真的没有看错,这个玩意儿,本质上就是一个
ServiceDescriptor
集合
当然,这个集合还做了一步services.BuildServiceProvider();
他是如何进行服务容器的构建的呢?我们往里面看看
public static ServiceProvider BuildServiceProvider(this IServiceCollection services, ServiceProviderOptions options)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
if (options is null)
{
throw new ArgumentNullException(nameof(options));
}
return new ServiceProvider(services, options);
}
BuildServiceProvider 是一个扩展方法,目的是通过IServiceCollection
去创建(new)一个ServiceProvider
3、ServiceProvider 服务提供者-创建
ServiceCollection
真的没有什么内容,现在我们看看ServiceProvider
,它主要在我们的流程里面做了两个事情
- BuildServiceProvider 的时候去new了一个出来
- 调用GetRequiredService 的时候,从服务容器中取出对应的服务
我们先看看它是如何new出来的
private readonly Func<ServiceIdentifier, ServiceAccessor> _createServiceAccessor;
// Internal for testing
internal