如何在netcore下,愉快的使用IServiceProvider
之前一直做dotnet framework开发,依赖注入使用Autofac,Autofac的一般用法是服务启动时,将用到的接口、实现类名注入进去,
然后在服务其他地方如果使用该类时,直接在Container里面Resolve出来即可。
后来使用netcore 2.1,框架本身使用了Microsoft.Extensions.DependencyInjection,是服务启动时,把需要注入的服务通过
public void ConfigureServices(IServiceCollection services)
实现依赖注入,在服务其他地方通过构造函数把服务实例化出来,然后实现具体方法的调用。
期初,因为场景比较简单,用起来比较舒服,后来随着业务复杂,就面临了一些挑战:
1)在服务的某个方法中,不想通过构造函数,现在想使用已经注入的接口方法,咋办?
为了解决这个问题,我们引入了IHttpContextAccessor(web服务),在IHttpContextAccessor里面有HttpContext,
在HttpContext里面有个RequestServices就是IServiceProvider类型,里面有我们想要的已经注入的服务:
public abstract class ControllerBase : Controller
{
protected ControllerBase(IMediator mediator, ILogger logger, IHttpContextAccessor accessor)
{
var configuration = accessor.HttpContext.RequestServices.GetRequiredService<IConfigurationManager>();
}
}
PS:使用HttpContext里面的RequestServices是有局限的,比如单元测试怎么写?(其实还是仿web的初始化,本次不讨论)
上面的使用HttpContext里面的RequestServices解决了一些问题,但是后来又遇到问题了
2)异步编程,Handler里面处理的逻辑比较耗时,所以我们打算把里面的逻辑抽出来使用异步方式,然后立刻返回结果,
立刻返回结果导致HttpContext.RequestServices变成了null,所以在异步调用逻辑中用到RequestServices的地方全部报错。
根据这个问题,我们在common项目里面增加ServiceLocator类:
public class ServiceLocator
{
public static IServiceProvider Services { get; private set; }
public static void SetServices(IServiceProvider services)
{
Services = services;
}
}
然后在 public void ConfigureServices(IServiceCollection services)
方法里面使用
// 将注入放在全局变量里维护
ServiceLocator.SetServices(serviceProvider);
PS:尽量在该方法的最下面使用这个赋值。
然后在你服务中的其他位置使用它拿到已经注入的接口

注意:在ServiceLocator里面使用的接口应该都是只读的实例,这样就不会产生更新操作,导致线程不安全的问题
如何在netcore下,愉快的使用IServiceProvider的更多相关文章
- .NetCore 下开发独立的(RPL)含有界面的组件包 (五)授权过滤参数处理
.NetCore 下开发独立的(RPL)含有界面的组件包 (一)准备工作 .NetCore 下开发独立的(RPL)含有界面的组件包 (二)扩展中间件及服 务 .NetCore 下开发独立的(RPL)含 ...
- 如何在 NetCore 中定义我们自己的JSON配置文件的管理器。
一.介绍 微软已经对外提供了新的平台,我们叫它们是 Net Core 平台,这个平台和 Net Framework 平台有本质的区别,这个最本质的区别就是微软的C#代码可以跨平台了.当前我们主流的3大 ...
- Chrome出了个小bug:论如何在Chrome下劫持原生只读对象
Chrome出了个小bug:论如何在Chrome下劫持原生只读对象 概述 众所周知,虽然JavaScript是个很灵活的语言,浏览器里很多原生的方法都可以随意覆盖或者重写,比如alert.但是为了保证 ...
- 如何在Chrome下Debug Mocha的测试
简介 经过前两篇文章的介绍,相信读者对Mocha应该有一定的认知了,本文重点讲述如何在Chrome下Debug Mocha Test, 方便你在测试fail的时候troubleshooting. 关键 ...
- 详细介绍如何在win7下首次实现通过Git bash向Github提交项目
详细介绍如何在win7下首次实现通过Git bash向Github提交项目 引自:http://jingpin.jikexueyuan.com/article/35944.html 作者: wddoe ...
- 如何在IIS7下配置ASP+ACCESS环境
如何在IIS7下配置ASP+ACCESS环境 | 浏览:901 | 更新:2013-01-16 17:46 1 2 3 4 5 6 7 分步阅读 默认装完IIS7之后,使用ASP程序会发现提示数据库连 ...
- 一步一步教你如何在linux下配置apache+tomcat(转)
一步一步教你如何在linux下配置apache+tomcat 一.安装前准备. 1. 所有组件都安装到/usr/local/e789目录下 2. 解压缩命令:tar —vxzf 文件名(. ...
- ActiveX控件的基本操作方法以及如何在VS2010下使用控件
在此,小编就介绍下ActiveX控件的基本操作方法以及如何在VS2010下使用控件,我们以一个程序为例, (1) 打开VS2010编译器(右键以管理员身份运行,因为ActiveX需要注册), ...
- 如何在Linux下拷贝一个目录呢
cp -af newadmin/movie/. uploadfile/mallvideo/ 如何在Linux下拷贝一个目录呢?这好像是再简单不过的问题了. 比如要把/home/usera拷贝到/m ...
随机推荐
- Andrew算法(我确实不懂Graham)
先解释一下:这两个算法分别都是凸包问题的算法,然后Andrew是Graham的变种,速度更快,更稳定,非常优秀,介于我已经把Graham写的莫名其妙的WA了,所以我选择了这种算法! 我认为在这里,还是 ...
- AtCoder Beginner Contest 169
比赛链接:https://atcoder.jp/contests/abc169/tasks A - Multiplication 1 #include <bits/stdc++.h> us ...
- hdu 6835 Divisibility 思维
题意: 给你一个10进制的b和x,对于任意的一个b进制的y.如果y每一位的和可以被x整除,且y可以被x整除:或者如果y每一位的和不可以被x整除,且y不可以被x整除.那么就输出T.否则输出F 题解: 代 ...
- 牛客编程巅峰赛S1第3场 - 青铜&白银 A.位数求和
题意:求所有\(n\)位数每位之和等于\(m\)的数的和. 题解:数据范围非常小,我们可以直接暴力枚举\(t\)到\(10*t\)的所有数字,逐位分解判断即可. 代码: class Solution ...
- 从网络I/O模型到Netty,先深入了解下I/O多路复用
微信搜索[阿丸笔记],关注Java/MySQL/中间件各系列原创实战笔记,干货满满. 本文是Netty系列第3篇 上一篇文章我们了解了Unix标准的5种网络I/O模型,知道了它们的核心区别与各自的优缺 ...
- 阿里云 MaxCompute(ODPS)
大数据产品架构 BASE - Dataworks ODPS - MaxCompute ODPS 功能组成(Open Data Process Service) ODPS 是旧称,阿里云公有云服务中现称 ...
- LINUX - 随机数
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h& ...
- Java之一个整数的二进制中1的个数
这是今年某公司的面试题: 一般思路是:把整数n转换成二进制字符数组,然后一个一个数: private static int helper1(int i) { char[] chs = Integer. ...
- HDU 3920 Clear All of Them I(状压DP)题解
题意:2n个点,一个起点,开n枪,每枪必须打两个点,花费为起点到其中一点距离加上两点距离.问打完2n个点的最小花费. 思路:很显然应该dp状态,然后枚举i j两个空位置去填,那么复杂度$O(20 * ...
- linux下新建用户
新建用户的两种方式: 一步步创建 useradd -m user1 #-m 是建立家目录 passwd user1 #设置密码 usermod -a -G root user1 #加入管理员 chsh ...