【问题标题】:HttpContext and Caching in .NET Core >= 1.0.NET Core >= 1.0 中的 HttpContext 和缓存
【发布时间】:2017-04-28 08:39:48
【问题描述】:

我正在尝试将一些库从旧的基于 MVC5 System.Web 的堆栈移植到 .Net Core。我遇到的一个问题是缓存的变化。例如,在 MVC5 中,我能够读写 i18n 相关数据:

[代码片段 1]

public static Dictionary<string, IEnumerable<CoreDictionaryResource>> DictionaryResourcesCache {
    get { return (Dictionary<string, IEnumerable<CoreDictionaryResource>>)HttpContext.Current.Cache(string.Concat(_Dictionary, DictionaryID, CultureID)); }
    set { HttpContext.Current.Cache(string.Concat(_Dictionary, DictionaryID, CultureID)) = value; }
}

但是,我可靠地得知System.Web 及其HttpContext 不包含缓存字段。我可以看到Current 字段,然后是其中的一大堆字段,例如ApplicationSession,但可惜没有Cache

我已经在Startup.cs 中完成了必要的操作,并且该应用程序被配置为在内存缓存和会话中使用。我知道会话可以正常工作,因为我使用

缓存了其他 POCO

[代码片段 2]

 return System.Web.HttpContext.Current.Session.GetObject<User>("AuthenticatedUser");

GetObject 在我创建的扩展中。

我是在尝试使用HttpContext 从缓存中读取数据,或者我需要使用IDistributedCache,如here, hereSO 所示。

但实际上我只是将方法移植到 [Code Snippet 1]...

您可以在新的 .Net Core 上提供有关缓存的任何指示都会非常有帮助。

仅供参考,我不希望控制器和视图中的任何逻辑。我正在构建的应用程序使用单独的 DLL 进行数据访问和逻辑,因此请不要将任何带有 DI 的示例发布到控制器中。这个问题更多是在基础设施级别,然后才影响到 MVC 堆栈。

谢谢大家。

【问题讨论】:

  • 另外,我们的 i18n 字符串不是使用 XML 存储的,而是存储在定制的数据库实例中……但是,这应该不是问题,因为数据访问层中的 CRUD 方法运行正常。我只需要弄清楚如何缓存这些服务器端并读出它们。
  • 但是现在,您可以在启动时使用services.AddMemoryCache(); 注册内存(或Redis 等分布式缓存),然后解析IDistributedCacheIMemoryCache 并在您的中间件中解析它。您不能使用静态字段,因为它违反了 ASP.NET Core 的 IoC/DI 特性和反模式。或者您为它创建一个包含逻辑的类。或者只是使用围绕数据库或内存缓存的新本地化功能,
  • 感谢 Tseng - 及时注意到。不幸的是,IoC/DI 不是神牛(事实上,SO 本身并不使用 DI,因为它会变得复杂且缓慢)。但是,IDistributedCache 似乎是一个不错的选择。正在考虑 AWS Elasticache 而不是 Redis,但是嘿!猪就是猪。您是否有示例或链接到 "new localization feature that's wrapping around an database or memory cache" 上的资源
  • 我的第二个命令中的链接链接到显示它的文件/存储库。定位器的用法在此处的文档中进行了描述docs.microsoft.com/en-us/aspnet/core/fundamentals/localization

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


【解决方案1】:

你应该只使用内存缓存,因为 HttpContext 缓存对象实际上是 appdomain 缓存对象,尽管它是使用 HttpContext 公开的

来自 msdn https://msdn.microsoft.com/en-us/library/system.web.httpcontext.cache(v=vs.110).aspx

每个应用程序域都有一个 Cache 类的实例。因此,Cache 属性返回的 Cache 对象是应用程序域中所有请求的 Cache 对象。

我们应该使用

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Caching.Memory;
using System;
using Microsoft.Extensions.FileProviders;

namespace CachingQuestion
{
public class Startup
{
    static string CACHE_KEY = "CacheKey";

    public void ConfigureServices(IServiceCollection services)
    {
        //enabling the in memory cache 
        services.AddMemoryCache();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        var fileProvider = new PhysicalFileProvider(env.ContentRootPath);

        app.Run(async context =>
        {
            //getting the cache object here
            var cache = context.RequestServices.GetService<IMemoryCache>();
            var greeting = cache.Get(CACHE_KEY) as string;


        });
    }
}

 public class Program
 {
    public static void Main(string[] args)
    {
          var host = new WebHostBuilder()
            .UseKestrel()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}
}

【讨论】:

    【解决方案2】:

    内存缓存功能仍然存在,只是稍微移动了一下。如果你添加

    "Microsoft.Extensions.Caching.Memory": "1.1.0"
    

    给你 project.json 文件和添加

            services.AddMemoryCache();
    

    对于您的 Startup.ConfigureServices 方法,您将设置一个单例内存缓存实例,该实例的工作方式与旧实例非常相似。您可以通过依赖注入获得它,因此具有构造函数的控制器可以获取实例。

    public class HomeController: Controller 
    {
        private IMemoryCache _cache;
        public HomeController(IMemoryCache cache) 
        {
            _cache = cache;
        }
    
    }
    

    然后您可以在上面的类中使用 _cache 来获取全局可用的单例类。您可能还想查看其他类型的缓存,包括用于进程外存储的 Redis 缓存。

    【讨论】:

    • 我收到此错误:“无法创建类型为 'Microsoft.Extensions.Caching.Memory.IMemoryCache' 的实例。模型绑定的复杂类型不能是抽象类型或值类型,并且必须具有无参数构造函数。” - 要修复它,您只需像这样更改它: public HomeController([FromServices] IMemoryCache cache)
    【解决方案3】:

    我的答案集中在如何以最简单和最快的方式将缓存实现从旧的 ASP.Net MVC 移植到 ASP.Net CORE,同时也关注不依赖依赖注入。


    与 ASP.Net MVC 的 HttpContext.Current.Cache 完全等效。它的实现旨在允许在框架之间轻松移植。这是:

    System.Runtime.Caching/MemoryCache
    这与过去的 ASP.Net MVC 的HttpRuntime.Cache 几乎相同。 您可以在 ASP.Net CORE 上使用它而无需任何依赖注入。使用方法如下:

    // First install 'System.Runtime.Caching' (NuGet package)
    
    // Add a using
    using System.Runtime.Caching;
    
    // To get a value
    var myString = MemoryCache.Default["itemCacheKey"];
    
    // To store a value
    MemoryCache.Default["itemCacheKey"] = myString;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      • 2016-12-14
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多