谈谈.NET Core IServiceProvider
【导读】最近重构部分代码,因历史原因在静态类中需使用注入实例,构造函数注入则不再可取,此时只能构造全局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相关推荐
- 谈谈.NET Core中基于Generic Host来实现后台任务
前言 很多时候,后台任务对我们来说是一个利器,帮我们在后面处理了成千上万的事情. 在.NET Framework时代,我们可能比较多的就是一个项目,会有一到多个对应的Windows服务,这些Windo ...
- 基于.NET下的人工智能|利用ICSharpCore搭建基于.NET Core的机器学习和深度学习的本地开发环境...
每个人都习惯使用Python去完成机器学习和深度学习的工作,但是对于习惯于某种特定语言的人来说,转型不是那么容易的事.这两年我花了不少时间在Python,毕竟工作的重心也从移动开发转为机器学习和深度学 ...
- 利用ICSharpCore搭建基于.NET Core的机器学习和深度学习的本地开发环境
每个人都习惯使用Python去完成机器学习和深度学习的工作,但是对于习惯于某种特定语言的人来说,转型不是那么容易的事.这两年我花了不少时间在Python,毕竟工作的重心也从移动开发转为机器学习和深度学 ...
- EFCore查缺补漏(一):依赖注入
前段时间,在群里潜水的时候,看见有个群友的报错日志是这样的: An unhandled exception was thrown by the application. System.OutOfMem ...
- 谈谈ASP.NET Core中的ResponseCaching
前言 前面的博客谈的大多数都是针对数据的缓存,今天我们来换换口味.来谈谈在ASP.NET Core中的ResponseCaching,与ResponseCaching关联密切的也就是常说的HTTP缓存 ...
- 探索 .NET Core 依赖注入的 IServiceProvider
在上一篇文章中,我们学习了Microsoft.Extensions.DependencyInjection中的IServiceCollection,包括服务注册转换为ServiceDescriptor ...
- [ASP.NET Core 3框架揭秘] 异步线程无法使用IServiceProvider?
标题反映的是上周五一个同事咨询我的问题,我觉得这是一个很好的问题.这个问题有助于我们深入理解依赖注入框架在ASP.NET Core中的应用,以及服务实例的生命周期. 一.问题重现 我们通过一个简单的实 ...
- 谈谈在.NET Core中使用Redis和Memcached的序列化问题
前言 在使用分布式缓存的时候,都不可避免的要做这样一步操作,将数据序列化后再存储到缓存中去. 序列化这一操作,或许是显式的,或许是隐式的,这个取决于使用的package是否有帮我们做这样一件事. 本文 ...
- 基于.NET CORE微服务框架 -谈谈surging API网关
1.前言 对于最近surging更新的API 网关大家也有所关注,也收到了不少反馈提出是否能介绍下Api网关,那么我们将在此篇文章中谈谈surging Api 网关 开源地址:https://gith ...
最新文章
- 成功解决UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 0: invalid continuation byt
- salero网店的官方邮箱设置
- Linux-No.04 Linux 设置定时任务发送邮件功能
- final 实例域+final类+final方法(阻止继承)
- Win下部署Django开发环境
- 是谁关闭了Linux抢占,而抢占又关闭了谁?
- sqlmap之tamper绕过
- 智能家居小知识普及篇——智能家居技术有哪些劣势
- Spark基本工作流程和作业调度
- python定义一个复数类complex_定义一个复数类Complex,使得下面的代码能够工作
- 了解云的一些基本概念
- m被3整除的c语言表达式,C语言编写函数fun,实现从整数m到n,能被3整除
- linux服务器光衰,linux下怎么查看光模块光功率
- 接受了微软丹棱君的专访!
- 【嵌入式算法】空间向量夹角公式及其应用
- 名正则言顺�谈服装品牌名称(二)
- 像外行一样思考,像专家一样实践(读书笔记)
- 客户端与服务器端交互原理
- AnyProxy 原理及使用
- 高仿手机QQ5.0界面框架