我想知道为Asp.Net MVC 5 C#保存应用程序站点范围设置的最佳方法是什么?
将在“布局”视图中共享的“应用程序名称”设置。
喜欢
©@ DateTime.Now.Year @ Website.name
我使用EF将设置存储在数据库的名称/值对中。
其他设置包括:
SMTP用户名和密码 端口设置
主题 API密钥(Twitter,Yahoo和Etc) 和其他设置。
我不想在web.config中存储任何这些设置
考虑将数据库中的设置加载到应用程序缓存中。
然后使用存储在应用程序缓存中的设置加载局部变量。
这种方式只会在每次重启应用程序时访问数据库而不是每次请求。
大约每20分钟或更长时间,不会少。
计划也使用存储库。
只需知道在应用程序加载速度,性能和安全性方面使用的最佳方法是什么。
此外,设置也可以通过管理员页面进行编辑。
答案 0 :(得分:3)
我同意,将设置存储在应用程序缓存中是最好的选择。但是,我会使用从缓存中提取的属性来屏蔽静态类后面的设置,如果没有加载缓存,则会回退到数据库。例如:
public static class AppSettings
{
private static void LoadSettings
{
// This is where you would call the DB and populate the cache
}
public static string AppName
{
get
{
if (Cache["appname"] == null)
LoadSettings();
return Cache["appname"];
}
}
}
通过此实现,您可以轻松地从代码库中的任何位置调用应用程序设置,并使其按预期运行。
答案 1 :(得分:2)
在我看来,你所提到的将是实现这一目标的最佳方式。
如果您有一个管理页面,那么将它们存储在数据库中似乎是一个明智的选择,并在Application_Start
中检索它们并在应用程序缓存中缓存它们,这样您就不必继续查询数据库
从这里开始,我建议配置您的IoC容器以从应用程序缓存中检索设置,然后在需要时将它们注入您的服务,控制器等 - 而不是直接引用应用程序缓存。
通过这种方式,您可以相应地模拟应用程序设置,同时还可以减少对应用程序缓存需求的依赖性,以防您在将来的某个时间点决定使用替代解决方案。
public static class SettingsFactory
{
private const string Key = "Application.Settings";
public static ApplicationSettings Settings
{
get
{
if (HttpContext.Current.Application[Key] == null)
{
HttpContext.Current.Application[Key] = LoadSettings();
}
return HttpContext.Current.Application[Key] as ApplicationSettings;
}
}
public static ApplicationSettings LoadSettings()
{
// Return/create instance of your application settings from your database.
return new ApplicationSettings();
}
}
[Serializable]
public class ApplicationSettings
{
public string ApplicationName { get; set; }
public string ApiKey { get; set; }
}
然后在IoC容器中配置您的设置,如下所示(此示例使用的是StructureMap):
this.For<ApplicationSettings>().Use(SettingsFactory.Settings);
这样,您的应用程序设置仅在它们被使用时创建,然后缓存在应用程序缓存中并从此后从缓存中返回。
答案 2 :(得分:0)
广泛同意JoeMighty和Charlie Pugh发布的解决方案(相应的upVoted)。
进一步阐述: 1)使用缓存依赖项,您可以在其中回调项目以缓存结果,以便在回调中您可以重新填充(而不是让第一个不幸的用户在首次需要项目时等待所有等待)。
Here's a link to the MSDN article on the overload you'll need to use when adding the cache item
2)如果您使用控制器的基本实现,您可以添加一个调用来覆盖OnActionExecuting,将所有这些设置放入ViewBag中的已知插槽(而不是污染整个地方的视图模型或直接访问缓存从你的意见),所以......像
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// get the item from the cache here (anon object used as a placeholder)
this.ViewBag.settingsfromcache = new { valuex = 12234 };
// in the view you should then, consistently, be able to access "@ViewBag.settingsfromcache.valuex"
base.OnActionExecuting(filterContext);
}
不可否认,我不惜一切代价回避使用ViewBag / tempData等,在某些情况下,它非常有用。