netcore3.0 IServiceCollection 依賴注入系統(三)


上篇重點講了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();

        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM