上篇重點講了netcore依賴注入系統是如何解析服務的
再回顧一下
ServiceProvider類繼承IServiceProvider接口,實現IServiceProvider接口的GetService方法
ServiceProvider又是根據ServiceProviderOptions類的Mode屬性創建對應的IServiceProviderEngine實例(真正的解析服務)
IServiceProviderEngine的實現有DynamicServiceProviderEngine、ExpressionsServiceProviderEngine、ILEmitServiceProviderEngine、RuntimeServiceProviderEngine
上面的實現類都繼承自ServiceProviderEngine抽象類
ServiceProviderEngine抽象類的CallSiteFactory對我們注冊的服務IEnumerable<ServiceDescriptor>進行轉換,轉換成對應的ServiceCallSite對象。
ServiceProviderEngine抽象類的屬性RuntimeResolver(CallSiteRuntimeResolver類型)也能解析服務。
DynamicServiceProviderEngine、ExpressionsServiceProviderEngine、ILEmitServiceProviderEngine、RuntimeServiceProviderEngine實現了ServiceProviderEngine抽象類的RealizeService方法解析服務
總結:ServiceProvider是服務的核心。
IServiceCollection的擴展方法:
/// <summary> /// Extension methods for building a <see cref="ServiceProvider"/> from an <see cref="IServiceCollection"/>. /// </summary> public static class ServiceCollectionContainerBuilderExtensions { /// <summary> /// Creates a <see cref="ServiceProvider"/> containing services from the provided <see cref="IServiceCollection"/>. /// </summary> /// <param name="services">The <see cref="IServiceCollection"/> containing service descriptors.</param> /// <returns>The <see cref="ServiceProvider"/>.</returns> public static ServiceProvider BuildServiceProvider(this IServiceCollection services) { return BuildServiceProvider(services, ServiceProviderOptions.Default); } /// <summary> /// Creates a <see cref="ServiceProvider"/> containing services from the provided <see cref="IServiceCollection"/> /// optionally enabling scope validation. /// </summary> /// <param name="services">The <see cref="IServiceCollection"/> containing service descriptors.</param> /// <param name="validateScopes"> /// <c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>. /// </param> /// <returns>The <see cref="ServiceProvider"/>.</returns> public static ServiceProvider BuildServiceProvider(this IServiceCollection services, bool validateScopes) { return services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = validateScopes }); } /// <summary> /// Creates a <see cref="ServiceProvider"/> containing services from the provided <see cref="IServiceCollection"/> /// optionally enabling scope validation. /// </summary> /// <param name="services">The <see cref="IServiceCollection"/> containing service descriptors.</param> /// <param name="options"> /// Configures various service provider behaviors. /// </param> /// <returns>The <see cref="ServiceProvider"/>.</returns> public static ServiceProvider BuildServiceProvider(this IServiceCollection services, ServiceProviderOptions options) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return new ServiceProvider(services, options); } }
BuildServiceProvider方法根據注冊的服務創建ServiceProvider對象,此時我們可以從ServiceProvider獲取到我們注冊的服務了
我們看下簡單的使用場景
public interface IUserService { string GetName(); } public class UserService : IUserService { public string GetName() { return "test"; } } class Program { static void Main(string[] args) { var services = new ServiceCollection(); services.AddTransient<IUserService, UserService>(); var provider = services.BuildServiceProvider(); var userService = provider.GetService<IUserService>(); var result = userService.GetName(); Console.WriteLine(result); Console.Read(); } }