我有一个这样的课程:
public class LocalizedDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
Func<object> modelAccessor, Type modelType, string propertyName)
{
var meta = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (string.IsNullOrWhiteSpace(propertyName))
return meta;
if (meta.DisplayName == null)
GetLocalizedDisplayName(meta, propertyName);
if (string.IsNullOrWhiteSpace(meta.DisplayName))
{
string resource = string.Format("{0}_{1}", meta.ContainerType.Name, meta.PropertyName).ToLower();
meta.DisplayName = string.Format("[{0}]", resource);
}
return meta;
}
private static void GetLocalizedDisplayName(ModelMetadata meta, string propertyName)
{
ResourceManager rm = new ResourceManager(typeof (i18n));
CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
string resource = string.Format("{0}_{1}", meta.ContainerType.Name, meta.PropertyName).ToLower();
meta.DisplayName = rm.GetString(resource, culture);
}
}
我想抽象出
这一行ResourceManager rm = new ResourceManager(typeof (i18n));
我想让这个类与i18n
类型无关。我希望能够在构造/初始化时指定资源管理器的类型,使该类更具通用性并将其放在独立的类库中。
我有什么选择?它可以用静态类完成,还是必须有非静态类?或者我可以保持原样,将rm
抽象为类字段并在构造函数中初始化它?
谢谢
更新:请注意,该类很可能会在global.asax.cs中的各种ASP.NET MVC站点中使用,如下所示:
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
ModelMetadataProviders.Current = new LocalizedDataAnnotationsModelMetadataProvider();
}
我从来没有直接引用或直接使用这个类,ASP.NET MVC可以完成所有工作。
答案 0 :(得分:4)
您可以使该类具有通用性:
public class LocalizedDataAnnotationsModelMetadataProvider<T> : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
Func<object> modelAccessor, Type modelType, string propertyName)
{
var meta = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (string.IsNullOrWhiteSpace(propertyName))
return meta;
if (meta.DisplayName == null)
GetLocalizedDisplayName<T>(meta, propertyName);
if (string.IsNullOrWhiteSpace(meta.DisplayName))
{
string resource = string.Format("{0}_{1}", meta.ContainerType.Name, meta.PropertyName).ToLower();
meta.DisplayName = string.Format("[{0}]", resource);
}
return meta;
}
private static void GetLocalizedDisplayName<T>(ModelMetadata meta, string propertyName)
{
ResourceManager rm = new ResourceManager(typeof (T));
CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
string resource = string.Format("{0}_{1}", meta.ContainerType.Name, meta.PropertyName).ToLower();
meta.DisplayName = rm.GetString(resource, culture);
}
然后像这样设置:
ModelMetadataProviders.Current = new LocalizedDataAnnotationsModelMetadataProvider<i18n>();
答案 1 :(得分:0)
假设类型i18n
在整个应用程序中是一致的,那么您有几个选项,它们都是控制反转 / 依赖注入的形式。最简单的事情是做这样的事情:
public class LocalizedDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
private static readonly Type _i18nType = I18nTypeProvider.GetI18nType();
private static void GetLocalizedDisplayName(ModelMetadata meta, string propertyName)
{
ResourceManager rm = new ResourceManager(_i18nType);
CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
string resource = string.Format("{0}_{1}", meta.ContainerType.Name, meta.PropertyName).ToLower();
meta.DisplayName = rm.GetString(resource, culture);
}
}
其中I18nTypeProvider.GetI18nType
是其他地方的另一个静态方法,它具有找到适当类型的逻辑并在运行时返回它(即反射)。
更好的选择是使用依赖注入产品,如Managed Extensibility Framework或NInject。