Абстрагировать тип в статическом методе в нестатическом классе - PullRequest
0 голосов
/ 24 августа 2011

У меня есть такой класс:

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 как поле класса и инициализировать его в конструкторе?

Спасибо

ОБНОВЛЕНИЕ: Обратите внимание, что класс, скорее всего, будет использоватьсяв различных сайтах ASP.NET MVC в global.asax.cs, например, так:

protected override void OnApplicationStarted()
{
    base.OnApplicationStarted();
    ModelMetadataProviders.Current = new LocalizedDataAnnotationsModelMetadataProvider();
}

Я никогда не ссылаюсь на этот класс и не использую его напрямую, ASP.NET MVC делает все под капотом.

Ответы [ 2 ]

4 голосов
/ 24 августа 2011

Вы можете сделать класс родовым:

    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>();
0 голосов
/ 24 августа 2011

Если предположить, что тип 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/

...