.netcore学习之startup的IServiceCollection的理解

一,根据我们学习过core,都知道我们是在ConfigureServices中注册服务的,也是将我们实现注入,如下startup的简单的ConfigureServices方法,

public void ConfigureServices(IServiceCollection services)
{
     services.AddTransient<ITestService, TestService>();
     services.AddControllers();
}

如下图,并且添加服务test,只是添加服务,而不是注入容器,

二,那我们就奇怪了,IServiceCollection只是添加服务而不是注入容器,那我们是不是可以推测,是使用IServiceCollection去构建容器呢,如下代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using TestCore.Interface;

namespace TestCore.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class TestController : ControllerBase
    {
        public string GetString()
        {
            ///模拟startup实例一个ServiceCollection
            ServiceCollection serviceCollection = new ServiceCollection();
            ///注册服务
            serviceCollection.AddTransient<ITestService, TestService>();
            //通过服务构建容器,ServiceProvider类型
            var serviceProvider = serviceCollection.BuildServiceProvider();
            ///获取容器中的服务ITestService
            var testService = serviceProvider.GetService<ITestService>();
            ///调服务的方法
            return testService.Get(); 
        }
    }
}

总结:

1,serviceCollection.BuildServiceProvider()用来构建容器,返回类型ServiceProvider

2,DI容器的IServiceProvider对象是通过调用IServiceCollection接口的扩展方法BuildServiceProvider创建的,IServiceCollection对象是一个存放服务注册信息的集合。如下图,看继承

 

 3,所以可以得出:服务注册就是创建出现相应的ServiceDescriptor对象并将其添加到指定IServiceCollection集合对象中的过程。

三,服务注册就是创建出现相应的ServiceDescriptor对象,那我们测试下给ServiceCollection添加一个ServiceDescriptor对象,如下代码

        public string GetStringByServiceDescriptor()
        {
            ///模拟startup实例一个ServiceCollection
            ServiceCollection serviceCollection = new ServiceCollection();

            ///注册服务,两种方式
            serviceCollection.TryAdd(new ServiceDescriptor(typeof(ITestService), new TestService()));
            //serviceCollection.TryAdd(new ServiceDescriptor(typeof(ITestService), m =>
            //{
            //    return new TestService();
            //}, ServiceLifetime.Transient));

            //通过服务构建容器,ServiceProvider类型
            var serviceProvider = serviceCollection.BuildServiceProvider();
            ///获取容器中的服务ITestService
            var testService = serviceProvider.GetService<ITestService>();
            ///调服务的方法
            return testService.Get();
        }

综上结论:DI容器的IServiceProvider对象是通过调用IServiceCollection接口的扩展方法BuildServiceProvider创建的,而IServiceCollection对象是一个存放服务注册信息的集合,而在DI框架中,服务注册信息的集合与之对应的类型为ServiceDescriptor

原文地址:https://www.cnblogs.com/May-day/p/13372348.html