我要求最终用户可以更改本地化资源,并且应在应用程序中显示更改,而无需重新启动应用程序。
更新以澄清方案:
我说的是在运行时更改本地化资源。可以说我在页面的德语翻译中有一个拼写错误。然后一些管理员用户应该有可能在运行时更改该错字。不需要重新部署或重新启动,以便将此更改反映在UI中。
我正在使用ASP.NET MVC3。
我有哪些选择?
我一直在研究编写一个从数据库加载资源的custom ResourceProvider。
这似乎没有太大的努力,但到目前为止我指出了两个缺点:
还有哪些其他选择?是否可以在运行时操作已部署的resx文件?
但我怀疑应用程序在检测到这些更改时会自动“重新启动”:我怀疑ASP.NET意识到resx文件已经更改,然后它会回收应用程序池并动态编译新的resx文件。
它是否正确?有没有办法解决这个问题?
我还没有考虑在部署之前将资源编译到附属程序集中。这甚至是Web应用程序的推荐方案吗?
但即使使用已编译的附属程序集,我怀疑ASP.NET会在动态更改这些程序集时重新启动应用程序。这是对的吗?
我对如何满足原始要求的经验感兴趣? 我会对我上面提到的选项的任何评论感兴趣。
答案 0 :(得分:1)
DataAnnotations接受ErrorMessageResourceType
,告知ValidationAttrributes访问资源的位置。您可以按如下方式传递:
[Required(
ErrorMessageResourceType = typeof(DynamicResources),
ErrorMessageResourceName = "ResourceKey")]
public string Username { get; set; }
通过为每个键创建具有静态属性的此参数的类型,您可以创建一个从数据库或其他实现加载资源的实现。然后,您可以将其与DRY的动态对象组合,并将实现移至TryGetMember
。然后可能使用T4模板在编译时从数据库生成静态,最后得到:
public class DynamicResources : DynamicObject
{
// move these into partial and generate using T4
public static string MyResource
{
get { return Singleton.MyResource; }
}
public static string MyOtherResource
{
get { return Singleton.MyOtherResource; }
}
// base implementation to retrieve resources
private static dynamic singleton;
private static dynamic Singleton
{
get { return singleton ?? (singleton = new DynamicResources()); }
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
// some logic here to look up resources
result = GetResourceKeyFromDatabase(binder.Name);
return true;
}
}
当然,如果资源不是静态属性,它将是完美的。