首页 > 其他分享 >ServiceScopeFactory的使用方式

ServiceScopeFactory的使用方式

时间:2024-05-27 21:58:16浏览次数:21  
标签:httpContext 方式 private next readonly 使用 ServiceScopeFactory scopeFactory public

上篇文章谈到在项目中遇到了一个问题,其实就是生命周期的问题,在构造函数的参数中使用了scope生命周期的服务,然后使用ServiceScopeFactory去解决这一问题 ,但是使用方式好像不太正确

上篇文章说遇到了问题,ServiceScopeFactory使用方式好像不太正确,为什么?因为构造这个管道的原计划是针对于每一个请求,但是现在好像变成了单例,代码如下:

public class MyMiddleware  
{  
    private readonly RequestDelegate _next;  
    private readonly IServiceScopeFactory _scopeFactory;  
  	private readonly IServiceScope serviceScope;
    private readonly IMyService _service;
    public MyMiddleware(RequestDelegate next, IServiceScopeFactory scopeFactory)  
    {  
        _next = next;  
        _scopeFactory = scopeFactory;  
        serviceScope = _scopeFactory.CreateScope();
        _service = serviceScope.ServiceProvider.GetRequiredService<IMyService>()
    }  
  
    public async Task InvokeAsync(HttpContext httpContext)  
    {  
           // 在这里使用 myService 做一些事情  
           myService.Handle(httpContext);
           // 调用下一个中间件  
            await _next(httpContext);  
        // 注意:一旦离开 using 块,服务范围将被释放,并且所有通过该范围解析的服务也将被释放  
    }  
}

如上所示代码,虽然也能跑,但是却搞不好就会有并发问题,因为所有的请求都是用的同一个_service,而我们本意是针对于每个httpcontext,都获取一个服务。但是也能跑 :)

而实际上我们想写的是如下的代码:

public class MyMiddleware  
{  
    private readonly RequestDelegate _next;  
    private readonly IServiceScopeFactory _scopeFactory;  
  
    public MyMiddleware(RequestDelegate next, IServiceScopeFactory scopeFactory)  
    {  
        _next = next;  
        _scopeFactory = scopeFactory;  
    }    
    public async Task InvokeAsync(HttpContext httpContext)  
    {  
        // 创建一个新的服务范围  
        using (var scope = _scopeFactory.CreateScope())  
        {  
            // 从服务范围中解析你需要的服务  
            var myService = scope.ServiceProvider.GetRequiredService<IMyService>();    
            // 在这里使用 myService 做一些事情    
            // 调用下一个中间件  
            await _next(httpContext);  
        }    
        // 注意:一旦离开 using 块,服务范围将被释放,并且所有通过该范围解析的服务也将被释放  
    }  
}

这意味着服务的实例是在每个请求的基础上创建的。这在处理依赖关系注入(DI)时特别有用,当你希望为每个请求创建新的服务实例时。

总结

两种方式都不能算错,主要是看用在什么情况下,如果业务较为复杂,有并发问题,当然还是下面的写法为好。

这里主要是记录一下当时脑抽写的代码。

标签:httpContext,方式,private,next,readonly,使用,ServiceScopeFactory,scopeFactory,public
From: https://www.cnblogs.com/guoxiaotian/p/18216602

相关文章

  • 系统编程练习题----使用消息队列实现两个进程之间的通信
    目录题目思路代码展示进程A进程B结果展示题目要求进程A创建一条消息队列之后向进程B发送SIGUSR1信号,进程B收到该信号之后打开消息队列并写入一段信息作为消息写入到消息队列中,要求进程B在写入消息之后,发SIGUSR2信号给进程A,进程A收到该信号则从消息队列中读取消息并输出消息正文......
  • 如何在中文输入法模式下,使用英文符号?
    1、为什么有这种需求?当你使用Notion等笔记服务时,它的输入语法命令是斜杠(/),而在中文输入法场景下按健输入的是顿号(、),需要切换输入法才可以输入英文符号。因此,期待可以在中文输入法场景下,输入英文符号。减少切换的烦恼。2、如何解决?Windows自带的微软输入法支持......
  • .NET 7 AOT 的使用以及 .NET 与 Go 互相调用
    目录背景C#部分环境要求创建一个控制台项目体验AOT编译C#调用库函数减少体积C#导出函数C#调用C#生成的AOTGolang部分安装GCCGolang导出函数.NETC#和Golang互调C#调用GolangGolang调用C#其他 背景其实,规划这篇文章有一段时......
  • 安装和使用delphi最后的余辉:lazarus集成编译环境@FreeBSD
    遥想当年,最牛最流行的两个编程IDE是Delphi和VisualBasic,结果这么多年下来,VB已经没有往昔的热度,而Delphi也已经消亡在历史的长河中。不过Delphi的精神没消失,lazarus坚守delphi的编程风格,散发delphi最后的余辉。Lazarus介绍Lazarus是一个基于FreePascal的跨平台集成开发环境(I......
  • json-server 快速搭建接口服务 使用教程
    json-server是一款小巧的接口模拟工具,一分钟内就能搭建一套Restful风格的API,尤其适合前端接口测试使用。只需指定一个json文件作为api的数据源即可,使用起来非常方便,30秒入门。进阶操作还支持分页,排序等操作,非常方便!开源地址主页地址:https://www.npmjs.com/package/js......
  • 使用istio服务网格作为api网关
    API网关作为客户端访问后端的入口由来已久,主要是管理“南北”流量,近几年开始流行ServiceMesh架构,主要是管理内部系统,(即“东西”流量),而像Istio这样的服务网格也有内置网关,可以将系统内外的流量置于统一控制之下。这通常会给Istio的初次用户带来困惑。ServiceMesh和A......
  • 如何免费使用GPT-4o?如何升级GPT4.0 Turbo?(内附详细步骤教程)
    01GPT-4o是什么?5月中旬,OpenAI发布了惊艳的GPT-4o。经过体验,我深感其强大,中文能力尤为突出,速度也远超目前的GPT-4。GPT-4o深夜发布!Plus免费可用!|OpenAI发布GPT-4o一夜创历史,超越所有AI语音助手!!早在5月11日,Sam在推文中透露:OpenAI并没有推出GPT-5或新的搜索......
  • 如何使用ADB shell设置Android设备的全局HTTP代理
    打开ADB调试这里使用蓝叠模拟器进行测试下载adbhttps://dl.google.com/android/repository/platform-tools-latest-windows.zip解压好,放哪都行在platform-tools目录下,右击空白处,选择“在终端中打开”开始操作建立连接.\adbconnectlocalhost:5555启动shell会话......
  • 进程间通信(管道)、多线程理论、开设多线程的两种方式、threading介绍、线程之间共享数
    【一】进程间通信(管道)借助于消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取出。这种通信方式是非阻塞的,即发送进程不需要等待接收进程的响应即可继续执行。multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的进程间通信(IPC)有两种方式:队列......
  • 《python本机环境多版本切换》-两种方式以及具体使用--venv/pyenv+pycharm测试
    阿丹:sourcemyenv/bin/activate    在开发使用rasa的时候发现自己安装的python环境是3.12的,和rasa不兼容,所以实践一下更换多python环境。使用虚拟环境在Python中使用虚拟环境来切换Python版本是一个常见的做法,这可以帮助你为不同的项目维持独立的Python环境和依赖......