Microsoft.Extensions.DependencyInjection 的内部工作方式

IServiceCollection

要开始使用 Microsoft 的 DI nuget 包构建 IOC 容器,首先要创建一个 IServiceCollection。你可以使用已经提供的 Collection:ServiceCollection

var services = new ServiceCollection();

这个 IServiceCollection 只不过是一个实现:IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable

以下所有方法都只是将 ServiceDescriptor 实例添加到列表中的扩展方法:

services.AddTransient<Class>(); //add registration that is always recreated
services.AddSingleton<Class>(); // add registration that is only created once and then re-used
services.AddTransient<Abstract, Implementation>(); //specify implementation for interface
services.AddTransient<Interface>(serviceProvider=> new Class(serviceProvider.GetService<IDependency>())); //specify your own resolve function/ factory method.
services.AddMvc(); //extension method by the MVC nuget package, to add a whole bunch of registrations.
// etc..

//when not using an extension method:
services.Add(new ServiceDescriptor(typeof(Interface), typeof(Class)));

IServiceProvider

serviceprovider 是’Compiling’的所有注册,以便它们可以快速使用,这可以通过 services.BuildServiceProvider() 完成,这基本上是一个扩展 mehtod:

var provider = new ServiceProvider( services, false); //false is if it should validate scopes

在幕后,IServiceCollection 中的每个 ServiceDescriptor 都被编译为工厂方法 Func<ServiceProvider, object>,其中 object 是返回类型,它是:Implementation 类型的创建实例,Singleton 或你自己定义的工厂方法。

这些注册被添加到 ServiceTable,它基本上是一个 ConcurrentDictionary,其关键是 ServiceType 和上面定义的 Factory 方法的值。

结果

现在我们有一个 ConcurrentDictionary<Type, Func<ServiceProvider, object>>,我们可以同时使用它来请求为我们创建服务。展示一个如何看待它的基本例子。

  var serviceProvider = new ConcurrentDictionary<Type, Func<ServiceProvider, object>>();
  var factoryMethod = serviceProvider[typeof(MyService)];
  var myServiceInstance = factoryMethod(serviceProvider)

这不是它的工作方式!

这个 ConcurrentDictionaryServiceTable 的属性,这是 ServiceProvider 的属性