之前一直做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的更多相关文章

  1. .NetCore 下开发独立的(RPL)含有界面的组件包 (五)授权过滤参数处理

    .NetCore 下开发独立的(RPL)含有界面的组件包 (一)准备工作 .NetCore 下开发独立的(RPL)含有界面的组件包 (二)扩展中间件及服 务 .NetCore 下开发独立的(RPL)含 ...

  2. 如何在 NetCore 中定义我们自己的JSON配置文件的管理器。

    一.介绍 微软已经对外提供了新的平台,我们叫它们是 Net Core 平台,这个平台和 Net Framework 平台有本质的区别,这个最本质的区别就是微软的C#代码可以跨平台了.当前我们主流的3大 ...

  3. Chrome出了个小bug:论如何在Chrome下劫持原生只读对象

    Chrome出了个小bug:论如何在Chrome下劫持原生只读对象 概述 众所周知,虽然JavaScript是个很灵活的语言,浏览器里很多原生的方法都可以随意覆盖或者重写,比如alert.但是为了保证 ...

  4. 如何在Chrome下Debug Mocha的测试

    简介 经过前两篇文章的介绍,相信读者对Mocha应该有一定的认知了,本文重点讲述如何在Chrome下Debug Mocha Test, 方便你在测试fail的时候troubleshooting. 关键 ...

  5. 详细介绍如何在win7下首次实现通过Git bash向Github提交项目

    详细介绍如何在win7下首次实现通过Git bash向Github提交项目 引自:http://jingpin.jikexueyuan.com/article/35944.html 作者: wddoe ...

  6. 如何在IIS7下配置ASP+ACCESS环境

    如何在IIS7下配置ASP+ACCESS环境 | 浏览:901 | 更新:2013-01-16 17:46 1 2 3 4 5 6 7 分步阅读 默认装完IIS7之后,使用ASP程序会发现提示数据库连 ...

  7. 一步一步教你如何在linux下配置apache+tomcat(转)

    一步一步教你如何在linux下配置apache+tomcat   一.安装前准备. 1.   所有组件都安装到/usr/local/e789目录下 2.   解压缩命令:tar —vxzf 文件名(. ...

  8. ActiveX控件的基本操作方法以及如何在VS2010下使用控件

    在此,小编就介绍下ActiveX控件的基本操作方法以及如何在VS2010下使用控件,我们以一个程序为例, (1)      打开VS2010编译器(右键以管理员身份运行,因为ActiveX需要注册), ...

  9. 如何在Linux下拷贝一个目录呢

    cp -af newadmin/movie/.   uploadfile/mallvideo/ 如何在Linux下拷贝一个目录呢?这好像是再简单不过的问题了. 比如要把/home/usera拷贝到/m ...

随机推荐

  1. 【poj 1961】Period(字符串--KMP 模版题)

    题意:给你一个字符串,求这个字符串到第 i 个字符为止的重复子串的个数. 解法:判断重复子串的语句很重要!!if (p && i%(i-p)==0) printf("%d % ...

  2. P1714 切蛋糕 dp+单调队列

    题意: 题目描述 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精. 某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到 ...

  3. AtCoder Beginner Contest 188 C - ABC Tournament (模拟)

    题意:有\(2^n\)个人站成一排比赛,刚开始每个人都和自己右边的人进行比赛,赢得人晋级下一轮(下标的小的在前面),不断重复这个过程,问最后拿到第二名的人的编号. 题解:根据题意,可以用vector直 ...

  4. 【ybt金牌导航1-2-6】【luogu P2467】地精部落

    地精部落 题目链接:ybt金牌导航1-2-6 / luogu P2467 题目大意 有一个排列,要使得每个位置要么都比两边高,要么比两边低. 而且一定要以一高一低的方式排列. 两边的只用比旁边的那个高 ...

  5. Dcoker命令使用详解

    Docker语法说明 docker [OPTIONS] COMMAND [arg...] OPTIONS --config=~/.docker :指定本地客户端配置文件. -D, --debug :开 ...

  6. Nginx 动静分离概述

    目录 Nginx 动静分离是什么 Nginx 动静分离配置 Nginx 动静分离是什么 Nginx 动静分离,指的是静态资源请求由 Nginx 处理,动态资源请求由 php-fpm 处理或 tomca ...

  7. 蓝桥杯-摔手机问题【dp】

    非常详细的题解:戳这里 例题:poj-3783 Balls Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 115 ...

  8. ZOJ 3430 Detect the Virus(AC自动机 + 模拟)题解

    题意:问你主串有几种模式串.但是所有串都是加密的,先解码.解码过程为:先把串按照他给的映射表变成6位数二进制数,然后首尾衔接变成二进制长串,再8位8位取变成新的数,不够的补0.因为最多可能到255,所 ...

  9. 可重入锁ReentrantLock解析

    说到可重入锁,先从AQS的ConditionObject说起,AQS的内部类ConditionObject是构建显示锁条件队列的基础.之前AQS的解析没有说这个内部类,这里和ReentrantLock ...

  10. prototype chain & prototype & __proto__

    prototype chain & prototype & proto prototype chain MDN https://developer.mozilla.org/en-US/ ...