问:
下面的代码,在ASP.NET Core的startup类中创建了一个MemoryCache并且存储了三个键值“entryA”,“entryB”,“entryC”,之后想在Controller中再把这三个键值从缓存中取出来,但是发现Controller中的构造函数依赖注入的IMemoryCache并不是startup类中的MemoryCache,因为Controller中的IMemoryCache没有任何键值对:
How do I access the MemoryCache instance in Startup that will be used by the rest of my web app? This is how I'm currently trying it:
public class Startup { public Startup(IHostingEnvironment env) { //Startup stuff } public void ConfigureServices(IServiceCollection services) { //configure other services services.AddMemoryCache(); var cache = new MemoryCache(new MemoryCacheOptions()); var entryOptions = new MemoryCacheEntryOptions().SetPriority(CacheItemPriority.NeverRemove); //Some examples of me putting data in the cache cache.Set("entryA", "data1", entryOptions); cache.Set("entryB", data2, entryOptions); cache.Set("entryC", data3.Keys.ToList(), entryOptions); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { //pipeline configuration } }
And the Controller where I use the MemoryCache
public class ExampleController : Controller { private readonly IMemoryCache _cache; public ExampleController(IMemoryCache cache) { _cache = cache; } [HttpGet] public IActionResult Index() { //At this point, I have a different MemoryCache instance. ViewData["CachedData"] = _cache.Get("entryA");//这里"entryA"从IMemoryCache中找不到,为null return View(); } }
答:
When you added the statement
services.AddMemoryCache();
you were in effect saying that you wanted a memory cache singleton that would get resolved wherever you injected IMemoryCache as you did in your controller. So instead of creating a new memory cache, you need to add values to the singleton object that was created. You can do this by changing your Configure method to something like:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMemoryCache cache ) { var entryOptions = new MemoryCacheEntryOptions().SetPriority(CacheItemPriority.NeverRemove); //Some examples of me putting data in the cache cache.Set("entryA", "data1", entryOptions); cache.Set("entryB", data2, entryOptions); cache.Set("entryC", data3.Keys.ToList(), entryOptions); //pipeline configuration }
Use Configure method, not ConfigureServices。
意思就是说在ASP.NET Core的startup类中Configure方法是在ConfigureServices方法之后执行的,而如果在ConfigureServices方法中调用了services.AddMemoryCache()来启用MemoryCache的依赖注入,那么就可以在Configure方法的参数中使用IMemoryCache了,ASP.NET Core会自动注入Configure方法的IMemoryCache参数。并且在后续的Controller中注入的也是同一个IMemoryCache参数的实例。
Use Configure
method, not ConfigureServices