简体   繁体   中英

Possible to use IMemoryCache in ASP.NET Core if it is *not* dependency injected?

So I have a need to use IMemoryCache in my ASP.NET Core application, in most places it is DI'd into the controllers and works as expected. Now I have a need to cache part of the menu, and the menu logic is called as part of the layout view. So, there isn't a controller to speak of. My Startup has the following in it already, which works well for other things:

services.AddMemoryCache();

The call that is part of the layout looks like this:

@(await new MenuUtility().DisplayNavBar(Html, showMenus))

The MenuUtility class, which is where the cache will be used, has a call that looks like this:

public class MenuUtility
{
  private IMemoryCache _cache;

    public MenuUtility()
    {
       _cache = HttpContext.Current.RequestServices.GetService<MemoryCache>();
    }

    // Rest of class logic
}

The problem is, the cache service I am looking to return is always null. Is there something I am forgetting? I tried to add services.AddScoped<MenuUtility>(); to the ConfigureServices call, thinking that this would allow me to pass the cache interface in the constructor, but since I am calling the MenuUtility explicitly I don't have the parameter of the cache to pass in.

I see a few questions here in SO that talk around this issue, but nothing that directly and correctly answers it.

Since this is my project for which I will forever be the only programmer, I would prefer a simple solution instead of suggestions to rearchitect a bunch of it, if I can't come up with a good solution I will just leave out the cache for this.

the menu logic is called as part of the layout view

You can still use the @inject directive inside layout Razor views to inject services into the view:

@inject MenuUtility menuUtility

@await menuUtility.DisplayNavBar(Html, showMenus)

To make that work, you will just need to register the MenuUtility as a service and then use constructor injection in your MenuUtility to resolve the IMemoryCache :

// in Startup.ConfigureServices
services.AddTransient<MenuUtility>();
public class MenuUtility
{
    private readonly IMemoryCache _cache;

    public MenuUtility(IMemoryCache cache)
    {
       _cache = cache;
    }

    // …
}

You should generally avoid having to create utilities and services using new . The chance is high that you do have some dependency on some framework component, and then you should definitely use dependency injection to resolve this dependency automatically.

Btw. HttpContext.Current should not compile in ASP.NET Core. If it does, chances are that you are running on the .NET Framework with System.Web referenced. That is the old ASP.NET which is completely incompatible to ASP.NET Core. You should absolutely not mix these two frameworks. In ASP.NET Core, there is no way to retrieve the current HttpContext statically. You have to use dependency injection at some point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM