Application Variables in ASP.NET Core 2.0

12,638

Solution 1

A lot has progressed in the last 100 years. Some time ago, I believe in ASP.NET 1.0, the Application object in ASP classic was superseded with caching (although the Application object was left in for backward compatibility with ASP classic).

AspNetCore has replaced the caching mechanism of ASP.NET and made it DI-friendly, but it is still very similar to how the state of things was in ASP.NET. The main difference is that you now need to inject it instead of using the static HttpContext.Current.Cache property.

Register the cache at startup...

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache();
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvcWithDefaultRoute();
    }
}

And you can inject it like...

public class HomeController : Controller
{
    private IMemoryCache _cache;

    public HomeController(IMemoryCache memoryCache)
    {
        _cache = memoryCache;
    }

    public IActionResult Index()
    {
        string companyName = _cache[CacheKeys.CompanyName] as string;

        return View();
    }

Then to make it work application wide, you can use a filter or middleware combined with some sort of cache refresh pattern:

  1. Attempt to get the value from the cache
  2. If the attempt fails
    • Lookup the data from the database
    • Repopulate the cache
  3. Return the value

public string GetCompanyName()
{
    string result;

    // Look for cache key.
    if (!_cache.TryGetValue(CacheKeys.CompanyName, out result))
    {
        // Key not in cache, so get data.
        result = // Lookup data from db

        // Set cache options.
        var cacheEntryOptions = new MemoryCacheEntryOptions()
            // Keep in cache for this time, reset time if accessed.
            .SetSlidingExpiration(TimeSpan.FromMinutes(60));

        // Save data in cache.
        _cache.Set(CacheKeys.CompanyName, result, cacheEntryOptions);
    }

    return result;
}

Of course, you could clean that up and make a service with strongly typed properties as a wrapper around your cache that is injected into controllers, but that is the general idea.

Note also there is a distributed cache in case you want to share data between web servers.

You could alternatively use a static method or a statically registered class instance, but do note if hosting on IIS that the static will go out of scope every time the application pool recycles. So, to make that work, you would need to ensure your data is re-populated using a similar refresh pattern.

The primary difference is that with caching there are timeout settings which can be used to optimize how long the data should be stored in the cache (either a hard time limit or a sliding expiration).

Solution 2

You could create a Singleton-class called ApplicationWideSettings. Give that class public Properties. Initialize all the values you need one time and then use them by accesing the only instance of your class via:

ApplicationWideSettings.Instance.PropertyName;

Just make sure the namespace of the ApplicationWideSettings-class is referenced when you want to access it.

I prefer this over global/static settings because you have one class to save all your globally available data.

If you are unsure what a Singleton is I can just suggest you look into this article from Jon Skeet:

C# In Depth: Implementing the Singleton Pattern in C#

Share:
12,638
Laurie Dickinson
Author by

Laurie Dickinson

I'm a freelance web developer specializing in ASP.NET WebForms/MVC C# development with a bit of AngularJS thrown in, though I make occasional forays into other technologies such as Joomla!, Drupal, PHP, etc. I've been doing this full time for over 15 years and still love it!

Updated on June 07, 2022

Comments

  • Laurie Dickinson
    Laurie Dickinson almost 2 years

    How would I go about setting and accessing application-wide variables in ASP.NET Core 2.0?

    Details: I have a variable, let's call it CompanyName, which resides in the database and is used on literally every page. I don't want to hit the database every time I need to display the CompanyName. 100 years ago, I would have set Application["CompanyName']=CompanyName but I understand that this is not the way to do things in .NET Core. What would be the alternative?