博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
谈谈.NET Core IServiceProvider
阅读量:4034 次
发布时间:2019-05-24

本文共 1795 字,大约阅读时间需要 5 分钟。

【导读】最近重构部分代码,因历史原因在静态类中需使用注入实例,构造函数注入则不再可取,此时只能构造全局IServiceProvider,所以本文稍微分析下IServiceProvider

要构造全局使用IServiceProvider,我们都知道不能在ConfigureServices方法中直接调用BuildServideProvider而获取,会提示引起额外的复制等等问题,这里就不用多说 。

构造全局IServiceProvider

首先我们给出对应接口以及具体实现

public interface IHelloService{   void SayHello();}public class HelloService : IHelloService{    public void SayHello()    {      Console.WriteLine("Hello");    }}

接着我们将其注入为单例形式

services.AddSingleton
();

最后我们在Configure方法中获取注入实例并调用实例方法,如下:

var serviceProvider = app.ApplicationServices;var service = serviceProvider.GetRequiredService
();service.SayHello();

看上述调用结果,没有任何毛病,接下来我们将其注入生命周期修改为Scope看看

此时将抛出如上异常,这里我将具体详细信息给出,如下:

Cannot resolve scoped service '...' from root provider

要是我们将生命周期修改为Transient,那么结果和Singleton一样可正常调用。看到上述异常信息,网上部分资料并没有说明根本原因,只是给出如下解决方案

serviceCollection.BuildServiceProvider(validateScopes: false);

接下来我们依然保持上述生命周期Scope不变,我们在Configure方法中传入IServiceProvider参数,结果会怎样呢?

此时我们将发现结果却能正常调用,并不会如上述使用属性而抛出异常,这二者到底有何区别?

依稀记得在使用.NET Core 2.x版本时也遇到过这问题,当时也是想都没想,直接进行如上配置大方的解决了问题。那么为何进行如上设置就可以了呢?抛异常的根本原因在哪里?

这是因为通过属性获取的是根部的IServiceProvider即(root IServiceProvider),而上述以方法参数传入的则是根部的孩子(child of the root)。

通过看这一块源码可通过如下代码来证明参数所传入的IServiceProvider的根部就是app.ApplicationServices

((Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)serviceProvider).Engine.Root

如下为上述类截图源码,由于上述类属于程序集内并未对外暴露,所以想要验证的童鞋可能只能下载依赖注入这块源码去验证才可

分析到这里,想必我们已经明了,只能通过IServiceProvider子级才能解析注入的Scope实例,因此要从根本上解决通过属性去获取到注入Scope实例,我们还需手动创建子级才可,如下:

var manualScope = app.ApplicationServices.CreateScope();var service = manualScope.ServiceProvider.GetRequiredService
();service.SayHello();

???? 属性获取的是根部的IServiceProvider即(root IServiceProvider),而以方法参数传入的则是根部的孩子(child of the root)。

???? 属性需创建子级IServiceProvider才可解析Scope服务

转载地址:http://qvkdi.baihongyu.com/

你可能感兴趣的文章
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>
一个ahk小函数, 实现版本号的比较
查看>>
IP报文格式学习笔记
查看>>
autohotkey快捷键显示隐藏文件和文件扩展名
查看>>
Linux中的进程
查看>>
学习python(1)——环境与常识
查看>>
学习设计模式(3)——单例模式和类的成员函数中的静态变量的作用域
查看>>
自然计算时间复杂度杂谈
查看>>
当前主要目标和工作
查看>>
Intellij IDEA启动优化,让开发的感觉飞起来
查看>>
使用 Springboot 对 Kettle 进行调度开发
查看>>
Kettle链接MySQL报错:Driver class 'org.gjt.mm.mysql.Driver' could not be found
查看>>
如何优雅的编程,lombok你怎么这么好用
查看>>
一文看清HBase的使用场景
查看>>
除了负载均衡,Nginx还可以做很多,限流、缓存、黑白名单
查看>>
解析zookeeper的工作流程
查看>>
搞定Java面试中的数据结构问题
查看>>
CentOS7 安装 MySQL8
查看>>