摘要在非静态类中静态方法中的类型

时间:2011-08-24 13:00:37

标签: c# static abstraction

我有一个这样的课程:

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可以完成所有工作。

2 个答案:

答案 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。

http://msdn.microsoft.com/en-us/magazine/ee291628.aspx

http://ninject.org/