如何在ASP.net核心中按请求缓存

时间:2017-06-03 20:33:02

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

我的旧代码如下所示:

    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它不是这个项目的选项

2 个答案:

答案 0 :(得分:11)

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

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。 AsyncLocal&LT; T&GT;

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

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

ThreadStatic in asynchronous ASP.NET Web API

答案 1 :(得分:1)

  

数据库或连接字符串不会相同   请求?

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

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

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