【问题标题】:What is single http request?什么是单http请求?
【发布时间】:2020-08-05 11:08:53
【问题描述】:

我正在研究 asp.net 核心,我遇到了 AddTransient、AddSingleton 和 AddScoped 等概念。它们的不同之处在于对象的生命周期。

1.Singleton 在整个应用程序中创建单个实例。它首次创建实例并在所有调用中重用相同的对象。

  1. Scoped 生命周期服务在范围内每个请求创建一次。它相当于当前范围内的单例。例如,在 MVC 中,它为每个 HTTP 请求创建一个实例,但它在同一个 Web 请求的其他调用中使用同一个实例。
  2. 瞬态生命周期服务在每次被请求时创建。此生命周期最适合轻量级、无状态的服务。

我想知道单个HTTP请求是什么意思?如果我重定向到另一个页面,这是否意味着它是另一个 HTTP 请求? P.S 我使用了来自AddTransient, AddScoped and AddSingleton Services Differences的上述定义

【问题讨论】:

    标签: http asp.net-core asp.net-core-mvc


    【解决方案1】:

    Scoped 是生命周期,有点难以理解。 首先,为什么它被称为 Scoped 而不是 PerRequest 等?

    原因是DI容器没有“请求”的概念。 但它确实有“范围”。 当您的应用程序启动时,它会创建“根”服务集合。 现在,当您的应用收到 HTTP 请求时,会从此根服务集合创建一个范围。 您在控制器等中获得的所有服务都是从这个范围获得的。 如果服务被定义为瞬态或作用域,则作用域将创建它们并在释放作用域时释放它们,也就是 HTTP 请求结束的时候。 但是,如果是单例,则作用域会从根服务集合中获取单个实例。

    这里的transient和scoped的区别在于,如果在同一个请求过程中请求了同一个服务,那么返回的是同一个scoped service的实例,而transients永远是新的实例。

    现在你的问题是,当你重定向用户时会发生什么?

    1. 您的应用收到请求
    2. 它返回一个 302 Found 状态码来重定向调用者,这结束了请求
    3. 用户向先前请求的响应中 Location 标头指定的 URL 发出新请求

    所以这是一个新的请求。

    【讨论】:

    • 感谢您的回答。我的下一个问题是当我尝试访问数据访问层中的代码并且有超过 1 种方法(例如 getEmpName、getEmpEmailID 等)时,在瞬态和作用域的情况下创建了多少对象?
    • 不同的方法调用还是会调用数据层对象的同一个实例吗?
    • @KunalRelan 看看this in the documentation 这些示例展示了生命周期如何专门用于 ASP.NET。如果 Guid 更改为新实例,您也可以使用我的答案中的代码。
    【解决方案2】:

    Scoped Lifetime 是指到服务器的单个 HTTP 连接

    一旦发送响应并关闭连接,注册为 Scoped 的对象就会被释放。

    所以一个重定向是两个请求;一个用于HTTP 302 redirection,一个用于目标页面。如果您实际上将服务注入到执行重定向的任何内容中,您可能只需要担心这一点。

    This answer discusses alternatives to redirection 将与 Scoped 服务一起使用。

    还请查看ASP.NET Documentation 的这一部分。这个简单的代码展示了 Scoped 生命周期是如何工作的。

    ScopedService.cs

    public class ScopedGuidService
    {
       public Guid ScopedGuid => Guid.NewGuid();
    }
    

    Startup.cs

    public class Startup
    {
       public void ConfigureServices(IServiceCollection services)
       {
           services.AddScoped<ScopedGuidService>();
       }
       
       public void Configure(IApplicationBuilder app)
       {
         // Middleware showing how Scoped / per request works
         app.Use((context, next) =>
         {
            var scopedGuidService = 
            context.RequestServices.GetRequiredService<ScopedGuidService>();
            return context.Response.WriteAsync(scopedGuidService.ScopedGuid.ToString());
        });
    }
    

    如果您运行此程序,您将为每个请求获得不同的 Guid。

    【讨论】:

      猜你喜欢
      • 2021-06-11
      • 2013-06-02
      • 2011-12-20
      • 2014-03-28
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      相关资源
      最近更新 更多