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

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

构造全局IServiceProvider

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

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

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

services.AddSingleton<IHelloService, HelloService>();

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


var serviceProvider = app.ApplicationServices;var service = serviceProvider.GetRequiredService<IHelloService>();
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<IHelloService>();
service.SayHello();

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

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

谈谈.NET Core IServiceProvider相关推荐

  1. 谈谈.NET Core中基于Generic Host来实现后台任务

    前言 很多时候,后台任务对我们来说是一个利器,帮我们在后面处理了成千上万的事情. 在.NET Framework时代,我们可能比较多的就是一个项目,会有一到多个对应的Windows服务,这些Windo ...

  2. 基于.NET下的人工智能|利用ICSharpCore搭建基于.NET Core的机器学习和深度学习的本地开发环境...

    每个人都习惯使用Python去完成机器学习和深度学习的工作,但是对于习惯于某种特定语言的人来说,转型不是那么容易的事.这两年我花了不少时间在Python,毕竟工作的重心也从移动开发转为机器学习和深度学 ...

  3. 利用ICSharpCore搭建基于.NET Core的机器学习和深度学习的本地开发环境

    每个人都习惯使用Python去完成机器学习和深度学习的工作,但是对于习惯于某种特定语言的人来说,转型不是那么容易的事.这两年我花了不少时间在Python,毕竟工作的重心也从移动开发转为机器学习和深度学 ...

  4. EFCore查缺补漏(一):依赖注入

    前段时间,在群里潜水的时候,看见有个群友的报错日志是这样的: An unhandled exception was thrown by the application. System.OutOfMem ...

  5. 谈谈ASP.NET Core中的ResponseCaching

    前言 前面的博客谈的大多数都是针对数据的缓存,今天我们来换换口味.来谈谈在ASP.NET Core中的ResponseCaching,与ResponseCaching关联密切的也就是常说的HTTP缓存 ...

  6. 探索 .NET Core 依赖注入的 IServiceProvider

    在上一篇文章中,我们学习了Microsoft.Extensions.DependencyInjection中的IServiceCollection,包括服务注册转换为ServiceDescriptor ...

  7. [ASP.NET Core 3框架揭秘] 异步线程无法使用IServiceProvider?

    标题反映的是上周五一个同事咨询我的问题,我觉得这是一个很好的问题.这个问题有助于我们深入理解依赖注入框架在ASP.NET Core中的应用,以及服务实例的生命周期. 一.问题重现 我们通过一个简单的实 ...

  8. 谈谈在.NET Core中使用Redis和Memcached的序列化问题

    前言 在使用分布式缓存的时候,都不可避免的要做这样一步操作,将数据序列化后再存储到缓存中去. 序列化这一操作,或许是显式的,或许是隐式的,这个取决于使用的package是否有帮我们做这样一件事. 本文 ...

  9. 基于.NET CORE微服务框架 -谈谈surging API网关

    1.前言 对于最近surging更新的API 网关大家也有所关注,也收到了不少反馈提出是否能介绍下Api网关,那么我们将在此篇文章中谈谈surging Api 网关 开源地址:https://gith ...

最新文章

  1. 成功解决UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 0: invalid continuation byt
  2. salero网店的官方邮箱设置
  3. Linux-No.04 Linux 设置定时任务发送邮件功能
  4. final 实例域+final类+final方法(阻止继承)
  5. Win下部署Django开发环境
  6. 是谁关闭了Linux抢占,而抢占又关闭了谁?
  7. sqlmap之tamper绕过
  8. 智能家居小知识普及篇——智能家居技术有哪些劣势
  9. Spark基本工作流程和作业调度
  10. python定义一个复数类complex_定义一个复数类Complex,使得下面的代码能够工作
  11. 了解云的一些基本概念
  12. m被3整除的c语言表达式,C语言编写函数fun,实现从整数m到n,能被3整除
  13. linux服务器光衰,linux下怎么查看光模块光功率
  14. 接受了微软丹棱君的专访!
  15. 【嵌入式算法】空间向量夹角公式及其应用
  16. 名正则言顺�谈服装品牌名称(二)
  17. 像外行一样思考,像专家一样实践(读书笔记)
  18. 客户端与服务器端交互原理
  19. AnyProxy 原理及使用
  20. 高仿手机QQ5.0界面框架

热门文章

  1. 在春意盎然的季节里初识GIT
  2. 程序一启动检查网络,如果没有网络就退出程序
  3. perl学习笔记——目录操作
  4. Object-C 类,对象,运行时,isa
  5. USENIX 最佳论文奖:擦除 Windows Azure 存储编码
  6. LuckyDraw bot有幸被提名为微软2019的People's Choice app
  7. outlook工具栏显示_Outlook 2007中的待办事项栏仅显示当前任务
  8. api游戏编程鼠标选择拖动_如何选择合适的游戏鼠标
  9. 【C】C语言结构体指针的语法
  10. ExecutorService——shutdown方法和awaitTermination方法