如何在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里面使用的接口应该都是只读的实例,这样就不会产生更新操作,导致线程不安全的问题
最新文章
- 【转】ofbiz数据库表结构设计
- 【译】Spring 4 + Hibernate 4 + Mysql + Maven集成例子(注解 + XML)
- DevExpress GridView属性说明
- Microsoft.Office.Interop.Word.Document.Open returns null on Windows Server 2008 R2
- fibonacci 数列及其应用
- 用C语言制作爱心
- uva401 - Palindromes结题报告
- Java解惑五:类之谜
- learn-python3
- C# 存储过程使用方法
- Spring框架(6)---AspectJ实现AOP
- 【译】10个机器学习的JavaScript示例
- python并发编程之协程知识点
- 如何执行shell命令
- toggle,hasClass
- 二、启用Docker支持
- 微信小程序开发记录
- 位运算&;,逻辑与and
- ALGO-120_蓝桥杯_算法训练_学做菜
- Maximum Average Subarray II LT644
热门文章
- Codeforces Round #552 (Div. 3) C. Gourmet Cat (数学,模拟)
- Codeforces Round #670 (Div. 2) C. Link Cut Centroids (dfs,树)
- (数据科学学习手札106)Python+Dash快速web应用开发——回调交互篇(下)
- pip&;conda 换源
- MySQL数据库系列(三)- MySQL常用引擎MyISAM和InnoDB区别详解
- woj1013 Barcelet 字符串 woj1014 Doraemon&#39;s Flashlight 几何
- EDA : quartus2 17.1lite + modelsim +verilog 使用流程
- 1. mac 手动安装nodejs搭建vue环境
- IDEA插件:快速删除Java代码中的注释
- 时间轴 timeline