【橙子老哥】.NetCore IOC依赖注入源码剖析(一)

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的好处。。。。。 这些留给大家仔细思考吧~

上面的示例的流程,我们分为三步

  1. services.AddTransient<IService,MyService>(); 将服务添加进服务容器中
  2. BuildServiceProvider 构建容器
  3. 通过GetRequiredService从容器中获取到对应的服务

services.AddTransient<IService,MyService>()往里面看看

ServiceDescriptor serviceDescriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
collection.Add(serviceDescriptor);

这3步主要是用到了3个核心对象

  1. ServiceCollection (服务容器,我们的向容器中添加的服务存储在这里)
  2. ServiceDescriptor (服务描述者,我们向容器中新增的东西会转换成这个)
  3. 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,它主要在我们的流程里面做了两个事情

  1. BuildServiceProvider 的时候去new了一个出来
  2. 调用GetRequiredService 的时候,从服务容器中取出对应的服务

我们先看看它是如何new出来的

        private readonly Func<ServiceIdentifier, ServiceAccessor> _createServiceAccessor;

        // Internal for testing
        internal 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值