【问题标题】:How to Per-Request caching in ASP.net core如何在 ASP.net 核心中按请求缓存
【发布时间】:2017-11-05 00:13:09
【问题描述】:

我的旧代码如下所示:

public static class DbHelper {
    // One conection per request
    public static Database CurrentDb() {
        if (HttpContext.Current.Items["CurrentDb"] == null) {
            var retval = new DatabaseWithMVCMiniProfiler("MainConnectionString");
            HttpContext.Current.Items["CurrentDb"] = retval;
            return retval;
        }
        return (Database)HttpContext.Current.Items["CurrentDb"];
    }
}

由于我们在核心中不再有 HttpContext 可以轻松访问,我怎样才能实现同样的目标?

我需要从任何地方轻松访问CurrentDb()

希望使用 MemoryCache 之类的东西,但具有请求生命周期。 DI 这不是这个项目的选择

【问题讨论】:

    标签: c# caching asp.net-core asp.net-core-mvc


    【解决方案1】:

    至少有 3 个选项可以在 ASP.NET Core 中为每个请求存储一个对象:

    1。依赖注入

    您可以完全重新设计旧代码:使用内置 DI 并使用以下工厂方法将 Database 实例注册为作用域(根据 Web 请求):

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<Database>((provider) =>
        {
            return new DatabaseWithMVCMiniProfiler("MainConnectionString");
        });
    }
    

    Introduction to Dependency Injection in ASP.NET Core

    .NET Core Dependency Injection Lifetimes Explained

    2. HttpContext.Items

    此集合在 HttpRequest 开始时可用,并在每个请求结束时被丢弃。

    Working with HttpContext.Items

    3.异步本地

    为每个当前异步上下文存储一个值(一种支持异步的[ThreadStatic])。这就是 HttpContext 的实际存储方式:HttpContextAccessor

    What's the effect of AsyncLocal<T> in non async/await code?

    ThreadStatic in asynchronous ASP.NET Web API

    【讨论】:

    • 是的,我已经探索过使用 DI,但它添加了太多样板代码,更不用说必须重写太多已经存在的代码。 DI 这个项目不行
    • @EduardoMolteni 有时最好保持完整的 .NET =) 看看这个“纯粹的邪恶”解决方案带回 HttpContext.Current:stackoverflow.com/a/40028901/5112433
    • 是的,我也在努力避免这种怪物,想使用 MemoryCache 之类的东西,但请求生命周期
    • @EduardoMolteni 你考虑过HttpContext.Items 吗?该集合在 HttpRequest 开始时可用,并在每个请求结束时被丢弃。您只需要将它作为参数传递给您的非控制器类。 docs.microsoft.com/en-us/aspnet/core/fundamentals/…
    • AsyncLocalHttpContext 好一点,因为使用AsyncLocal 的代码更通用,并且不依赖于知道它是在HTTP 调用的上下文中。
    【解决方案2】:

    数据库或连接字符串不会在整个数据库中相同吗? 请求?

    如果是这样,那么您可以通过静态变量和中间件来实现。

    中间件会检查并设置每个请求开始时的信息,静态变量会存储该值,然后您的方法可以从静态变量中读取它。

    其他更简单的方法是将 IHttpContextAccessor 作为参数注入/传递。有了这个,你可以做最小的改变,但你可以从每个调用方法传递 IHttpContextAccessor 服务。

    【讨论】:

      猜你喜欢
      • 2019-05-23
      • 1970-01-01
      • 2021-12-08
      • 2023-03-11
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      相关资源
      最近更新 更多