[英]Abstract away the type in a static method in a non-static class
我有这样的课:
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会做所有事情。
您可以使该类通用:
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>();
假设类型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。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.