我该如何在ASP.NET Core 2.0中设置和访问应用程序范围的变量?
细节:我有一个变量,我们称之为CompanyName,它驻留在数据库中,并在每个页面上使用。 我不想每次显示CompanyName时都访问数据库。 在100年前,我会设置 Application["CompanyName']=CompanyName
,但我理解在.NET Core中这不是正确的做法。那么应该使用什么替代方法呢?
我该如何在ASP.NET Core 2.0中设置和访问应用程序范围的变量?
细节:我有一个变量,我们称之为CompanyName,它驻留在数据库中,并在每个页面上使用。 我不想每次显示CompanyName时都访问数据库。 在100年前,我会设置 Application["CompanyName']=CompanyName
,但我理解在.NET Core中这不是正确的做法。那么应该使用什么替代方法呢?
在过去的100年里,有很多进展。我相信在ASP.NET 1.0时期,ASP Classic中的Application对象被(缓存)所取代(尽管为了向后兼容性而保留了Application对象)。
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();
}
}
你可以像这样注入它...
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();
}
为了使其在整个应用程序中起作用,您可以使用过滤器或中间件与某种缓存刷新模式相结合:
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;
}
当然,你可以清理一下,创建一个带有强类型属性的服务,作为包装器注入到控制器中的缓存中,但这是一般性的想法。
还要注意,如果您想在Web服务器之间共享数据,则可以使用分布式缓存。
你也可以使用静态方法或静态注册的类实例,但请注意如果在IIS上托管,那么静态方法每次应用程序池重启时都会失效。因此,为了使其正常工作,需要使用类似刷新模式重新填充数据。
主要区别在于,使用缓存时有超时设置,可用于优化数据在缓存中存储的时间(硬时间限制或滑动过期)。
你可以创建一个名为ApplicationWideSettings的单例类。给该类公共的属性(Properties)。初始化所有需要的值一次,然后通过访问类的唯一实例来使用它们:
ApplicationWideSettings.Instance.PropertyName;
访问ApplicationWideSettings类时,请确保引用其命名空间。
与全局/静态设置相比,我更喜欢这种方法,因为你只需要一个类来保存所有全局可用的数据。
如果您不确定Singleton是什么,我建议您阅读Jon Skeet的这篇文章: