asp.net core 依赖注入实现全过程粗略剖析(2)

接着 上篇 目前也算是交代清楚了相关的类。那么框架具体是如何来实例化的呢?整个的流程是怎么样的。

我们参考源码中的Test文件夹来看看:

var collection = new ServiceCollection();
collection.AddTransient<DependOnNonexistentService>();
var provider = CreateServiceProvider(collection);

protected override IServiceProvider CreateServiceProvider(IServiceCollection collection) => collection.BuildServiceProvider();

public static ServiceProvider BuildServiceProvider(this IServiceCollection services)
{
    return BuildServiceProvider(services, ServiceProviderOptions.Default);
}

public class ServiceProviderOptions
{
    // Avoid allocating objects in the default case
    internal static readonly ServiceProviderOptions Default = new ServiceProviderOptions();

    /// <summary>
    /// <c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>.
    /// </summary>
    public bool ValidateScopes { get; set; }

    internal ServiceProviderMode Mode { get; set; } = ServiceProviderMode.Dynamic;
}

internal enum ServiceProviderMode
{
    Dynamic,
    Runtime,
    Expressions,
    ILEmit
}

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);
}

internal ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options)
{
    IServiceProviderEngineCallback callback = null;
    if (options.ValidateScopes)
    {
        callback = this;
        _callSiteValidator = new CallSiteValidator();
    }
    switch (options.Mode)
    {
        case ServiceProviderMode.Dynamic:
            _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback);
            break;
        case ServiceProviderMode.Runtime:
            _engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback);
            break;
#if IL_EMIT
        case ServiceProviderMode.ILEmit:
            _engine = new ILEmitServiceProviderEngine(serviceDescriptors, callback);
            break;
#endif
        case ServiceProviderMode.Expressions:
            _engine = new ExpressionsServiceProviderEngine(serviceDescriptors, callback);
            break;
        default:
            throw new NotSupportedException(nameof(options.Mode));
    }
}
View Code

如上所示,就是注入服务,实例化服务的整个过程了。我们主要是根据IServiceCollection的扩展方法BuilServiceProvider调用ServiceProvider类,进而实例化相关服务。

除去这种方式实现ServiceProvider外,默认asp.net core框架中还有一个DefaultServiceProviderFactory。不过这个工厂类最后也是调用IServiceCollection接口的拓展方法--BuildServiceProvider来创建ServiceProvider类。


总结:
IServiceCollection接口的拓展方法Addxxx 收集需要注入的服务,服务实现类型,服务的生命周期。这些就是在ServiceDescriptor中获取到的,也是该类的属性对象。这个也是IServiceCollection继承自IList<ServiceDescriptor>的解释所在。随后再获取ServiceProviderOptions枚举对象,选择实现实例化的类型,比如反射等。最后就是调用BuildServiceProvider来生成ServiceProvider了。ServiceProvider根据选择之前的选择及配置,实例化服务。

猜你喜欢

转载自www.cnblogs.com/zhiyong-ITNote/p/9388277.html
今日推荐