2011-08-24 178 views
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的類indenpendent。我希望能夠指定施工/初始化資源管理器的類型,使類更具有普遍性和把它放在一個獨立的類庫。

我有什麼選擇?可以將其與靜態類做或做我必須有非靜態類?或者,我可以只留下事情是這樣的,抽象rm爲類字段並在構造函數初始化呢?

謝謝

UPDATE:請注意,類將最有可能在不同的ASP.NET MVC站點使用中的global.asax.cs這樣的:

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

我從來沒有實際引用或直接使用這個類,ASP.NET MVC將一切盡在掌握之中。

+0

這是否有過簡單地對用指定的(假設'資源類型和資源名稱模特屬性'DisplayAttribute'聲明DisplayAttribute'正常工作,您正在使用的框架有什麼好處(例如,它在MVC3中工作正常,但不是MVC2)) –

+0

巨大的優勢,因爲它允許我們完全跳過DisplayAttribute,並默認使用此ModelData提供程序來提供資源字符串 - 我發現編寫屬性非常耗時,尤其是與對資源名稱的引用。這是完美的工作,現在我只想使它更通用 – mare

回答

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

這可以工作,但檢查出我提供的更新的代碼,我把類連接到當前的ModelMetaDataProvider。我必須以某種方式將T型語言帶入課堂。 – mare

+0

我更新了您的代碼,並完成了對代碼的額外修改。既然你引導了我正確的方向,我接受你的答案。 – mare

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在別處另一種靜態方法有找到合適的類型,並在運行時(即反射)返回它的邏輯。

一個更好的選擇是使用依賴注入產品如託管擴展框架或NInject。

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

http://ninject.org/