ASP.NET Core 2.0中的应用程序变量

Lau*_*son 14 c# asp.net asp.net-core asp.net-core-2.0

我如何在ASP.NET Core 2.0中设置和访问应用程序范围的变量?

细节: 我有一个变量,我们称之为CompanyName,它存在于数据库中,并且几乎每个页面都使用它.每次我需要显示CompanyName时,我都不想访问数据库.100年前,我会设置Application["CompanyName']=CompanyName但我明白这不是在.NET Core中做事的方法.会有什么选择?

Nig*_*888 12

在过去的100年中取得了很大进展.前段时间,我相信ASP.NET 1.0,ASP经典中的Application对象被取代了缓存(虽然Application对象是为了向后兼容ASP经典而留下的).

AspNetCore 取代了ASP.NET的缓存机制并使其对DI友好,但它仍然非常类似于ASP.NET中的状态.主要区别在于您现在需要注入它而不是使用静态HttpContext.Current.Cache属性.

在启动时注册缓存...

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以像...那样注入它

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();
    }
Run Code Online (Sandbox Code Playgroud)

然后,为了使它在应用程序范围内工作,您可以使用过滤器中间件与某种缓存刷新模式相结合:

  1. 尝试从缓存中获取值
  2. 如果尝试失败
    • 从数据库中查找数据
    • 重新填充缓存
  3. 返回值

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;
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以清理它并使用强类型属性创建服务作为注入控制器的缓存的包装器,但这是一般的想法.

另请注意,如果要在Web服务器之间共享数据,则需要使用分布式缓存.

您也可以使用静态方法或静态注册的类实例,但请注意,如果在IIS上托管,每次应用程序池回收时静态都将超出范围.因此,为了实现这一目标,您需要确保使用类似的刷新模式重新填充数据.

主要区别在于,使用缓存时,可以使用超时设置来优化数据应存储在缓存中的时间(硬时间限制或滑动到期时间).


Pau*_*and 5

您可以创建一个称为ApplicationWideSettings的Singleton类。给该类提供公共属性。一次初始化您需要的所有值,然后通过以下方式访问类的唯一实例来使用它们:

ApplicationWideSettings.Instance.PropertyName;
Run Code Online (Sandbox Code Playgroud)

只需确保要访问ApplicationWideSettings-class的名称空间即可。

与全局/静态设置相比,我更喜欢此设置,因为您可以使用一个类来保存所有全局可用数据。

如果您不确定什么是Singleton,我可以建议您看一下Jon Skeet的这篇文章:

C#深入:在C#中实现单例模式