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)
這不是它的工作方式!
這個 ConcurrentDictionary
是 ServiceTable
的屬性,這是 ServiceProvider
的屬性