c# - 对于 AddScoped(), "within the same HTTP request"是什么意思

标签 c#

我试图了解 AddSingletonAddScopedAddTransient 之间的区别。有很多解释,但我看不懂,因为我不明白什么时候HTTP请求在同一个范围内

最佳答案

因此,在 AppDomain 或正在运行的进程中,始终存在一个由所有使用者共享的“根容器”。然后为每个 HTTP 请求创建子容器(在 ASP.NET Core 中,为每个包含 HttpRequestHttpResponseHttpContext)。 (请注意,也可以出于其他原因创建子容器,但这不在本答案的关注范围之内)。

  • Singleton 服务仅构造一次,通常仅由根容器构造。它们就像 OOP 中的单例模式(其中一个类只能实例化一次),除了在这种情况下您仍然可以手动创建多个实例,但 DI 容器本身只会创建 1 个实例。

    • 您可以通过从服务工厂方法返回 OOP 单例实例来将 OOP 单例与 DI 容器一起使用。
  • Transient 服务总是在被请求时创建 - 它们注定是短期服务。一些容器会对其创建的所有 transient 服务调用 IDisposable.Dispose,而其他容器则不会(因为它们希望消费者处置它们,请检查您的容器的政策)。

  • 请求范围的服务可以由不同的容器系统以不同的方式实现 - 但我看到的一种常见方法是在每个 HTTP 请求开始时(当创建一个新的 HttpContext 时) child-container 被创建(子容器继承其父容器的注册),然后它创建的所有对象(通常作为单例,但仅在该子容器中)然后被释放(如果适用) 当 HTTP 请求结束时(当 HttpContext 被销毁时,在 HTTP 响应已发送到客户端并且响应结束后)。

完全忽略 ASP.NET - 让我们假设我们有自己的 HTTP 服务器程序和它自己的 DI 容器:

public class HttpServer
{
    private readonly IContainer rootContainer;

    public HttpServer()
    {
        this.rootContainer = RegisterServices( new ContainerBuilder() ).Build();

    }

    private static IContainerBuilder RegisterServices( IContainerBuilder services )
    {
        return services
            .RegisterSingleton<ISystemClock,BiosClock>()
            .RegisterSingleton<MySingleton>( factory: () => MySingleton.Instance )
            .RegisterTransient<IDbConnection>( factory: () => new SqlConnection() )
            .RegisterRequest<RequestTracingService>();
    }

    public void OnHttpRequest( Socket socket )
    {
        HttpContext context = new HttpContext();
        context.RequestContainer = this.rootContainer.CreateChildContainer();

        try
        {
            // hand-off the `context` object to code that reads the request, does processing, and then writes the response
        }
        finally
        {
            context.RequestContainer.Dispose(); // <-- this disposes of any objects created by RequestContainer during the processing of the request, without touching any objects created by `rootContainer`.
        }
    }
}

关于c# - 对于 AddScoped(), "within the same HTTP request"是什么意思,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57350302/

相关文章:

c# - 使用异步时未处理 SqlConnection

c# - 我应该如何防止在这里多次插入?

c# - 在我的 asp.net mvc web 应用程序中使用 Parallel.Foreach 和 WebClient() 有什么缺点或风险吗

c# - Asp.Net Web Api Multipost 参数

c# - 如何逻辑排序字符串

c# - 任务继续被安排到非线程池线程。为什么?

c# - 检测前台窗口的哪个子窗口被点击?

c# - 404自定义重定向

c# - 如何创建带有倾斜边框的文本框和标签?

c# - 有没有办法等待所有任务直到特定结果为真,然后取消其余的?