抽象出非静态类中静态方法中的类型

发布于 2024-12-01 07:45:00 字数 1922 浏览 1 评论 0原文

我有一个这样的类:

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 在幕后做所有事情。

I have a class like this:

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);
    }
}

I want to abstract away the line

ResourceManager rm = new ResourceManager(typeof (i18n));

I want to make this class indenpendent of the type i18n. I want to be able to specify the type for the resource manager at construction/initialization, making the class more universal and put it in a standalone class library.

What are my options? Can it be done with a static class or do I have to have non-static class? Or can I just leave the way it is, abstract the rm as class field and initialize it in the constructor?

Thank you

UPDATE: Please note the class will most likely be used in various ASP.NET MVC sites in global.asax.cs like this:

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

I am never actually referencing or using this class directly, ASP.NET MVC does everything under the hood.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦言归人 2024-12-08 07:45:00

您可以使该类通用:

    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>();

You can make the class generic:

    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);
    }

And set it up like this:

ModelMetadataProviders.Current = new LocalizedDataAnnotationsModelMetadataProvider<i18n>();
骄兵必败 2024-12-08 07:45:00

假设类型 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 是其他地方的另一个静态方法,它具有查找适当类型并在运行时返回它的逻辑(即反射)。

更好的选择是使用依赖注入产品,例如托管扩展性框架或 NInject。

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

http://ninject.org/

Assuming type i18n is consistent across the entire application, then you have a few options, which all are forms of Inversion of Control / Dependency Injections. The simplest thing is to do something like this:

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);
    }
}

Where I18nTypeProvider.GetI18nType is another static method elsewhere that has the logic to find the appropriate type and return it at runtime (i.e., reflection).

An even better option is to use an dependency injection product like Managed Extensibility Framework or NInject.

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

http://ninject.org/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文