一,根据我们学习过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