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


    接着 前面,前面的过程是普遍常用的依赖注入解析过程,我们正常都是在startup类中注入依赖服务,但是,笔者这周开发的时候遇到个问题,不同服务的生命周期不同,不能调用服务。举个例子,AddDbContext注入数据库上下文,生命周期默认是scoped,但是我有个需求注入的服务是单例的,因此我注入的单利服务不能引用数据库上下文来调用数据库,最后是通过CreateScoped来解决的。因此,这篇文章说到说到CreateScoped。

    public static IServiceScope CreateScope(this IServiceProvider provider)
    {
        return provider.GetRequiredService<IServiceScopeFactory>().CreateScope();
    }
    View Code

    最终是由获取接口IServiceScopeFactory的服务(也就是接口的实现类),由服务调用其CreateScope方法,作为返回值。

     GetRequiredService方法的最终实现:

    public static object GetRequiredService(this IServiceProvider provider, Type serviceType)
    {
        provider.GetService(serviceType);
    }
    View Code

    由接口IServiceProvider的实现类来获取指定的服务。
    IServiceProvider接口,有三个实现类:
    ServiceProviderEngineScope
    ServiceProviderEngine
    ServiceProvider
    查看源码可知,而这三个类最终都是调用IServiceProviderEngine接口的GetService方法。该接口的实现类有多个如下:
    DynamicServiceProviderEngine
    RuntimeServiceProviderEngine
    ILEmitServiceProviderEngine
    ExpressionsServiceProviderEngine
    CompiledServiceProviderEngine
    ServiceProviderEngine
    前五个类都是直接继承自类ServiceProviderEngine,同时这五个类的实现都是通过特定的方式来实例化指定接口,也就是返回一个接口的服务对象。
    ServiceProviderEngine类的实现签名:

    internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory
    {}
    View Code

    也就是说最后所有的实现都是基于IServiceProviderEngine以及IServiceScopeFactory接口。

    internal interface IServiceProviderEngine : IDisposable, IServiceProvider
    {
        IServiceScope RootScope { get; }
    }
    public interface IServiceScopeFactory
    {
        IServiceScope CreateScope();
    }
    View Code

    IServiceScope接口的定义:

    public interface IServiceScope : IDisposable
    {
        IServiceProvider ServiceProvider { get; }
    }
    View Code

    这趟下来,就获取了接口IServiceScopeFactory的服务。随后就通过服务调用CreateScope方法。上面说了继承自接口IServiceScopeFactory的类有五个,最后都是继承自ServiceProviderEngine,这里调用CreateScope方法,最后也是调用ServiceProviderEngine类的CreateScope方法。签名如下:

    public IServiceScope CreateScope()
    {
        if (_disposed)
        {
            ThrowHelper.ThrowObjectDisposedException();
        }
    
        return new ServiceProviderEngineScope(this);
    }
    View Code

    返回一个接口IServiceScope的实例化类。该方法签名如下:

    internal class ServiceProviderEngineScope : IServiceScope, IServiceProvider
    {
        
    }
    View Code

    最后我们还是调用ServiceProviderEngine类实例来调用GetService方法获取指定接口的服务。
    举个实例使用的代码示例:

    using (var _scope = _serviceProvider.CreateScope())
    {
        var _context = _scope.ServiceProvider.GetService<PracticeDevDbContext>();
    }

    也就是说,是用CreateScope方法来解析接口获取服务,并不是直接的调用ServiceProvider来获取接口的服务,而是通过类外的IServiceScope来
    解析指定的接口获取服务,转了个弯。
    那么为什么要这么实现呢?其实我并不清楚,只是遇到了一个依赖注入的问题,最后是通过如上代码解析上下文类获取数据的。后续有待研究。

  • 相关阅读:
    java堆和栈的区别
    什么是java 序列化,如何实现java 序列化?
    HashMap和Hashtable的区别
    [LeetCode] 548. Split Array with Equal Sum 分割数组成和相同的子数组
    [LeetCode] 533. Lonely Pixel II 孤独的像素 II
    [LeetCode] 531. Lonely Pixel I 孤独的像素 I
    [LeetCode] 205. Isomorphic Strings 同构字符串
    [LeetCode] 351. Android Unlock Patterns 安卓解锁模式
    Python list、tuple、dict区别
    Minimum number of swaps required to sort an array
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/9419152.html
Copyright © 2020-2023  润新知