2010-02-25 52 views
6

我有我的應用程序的詳細配置信息存儲在一個表像下面:如何將namevaluecollection自動映射到強類型類?

SettingName     SettingValue 
--------------------   --------------------- 
PostsPerPage     10 
EmailErrors     True 
AdminEmailAddress    [email protected] 

我的數據訪問類說回報存儲在表中設置的NameValueCollection中/ keyvaluepair。

什麼是將namevaluecollection/keyvaluepair映射到強類型類的最佳方式,如下面那個名爲與SettingName列相同的屬性。

public class Settings 
{ 
    public int PostsPerPage{get;set;} 
    public bool EmailErrors{get;set;} 
    public string AdminEmailAddress{get;set;} 
} 
+0

是有一些原因,你需要轉而使用的app.config/web.config中的這種古怪的格式? – 2010-02-25 22:49:12

回答

2

使用反射。在僞代碼:

Settings mySettingsClass = new Settings(); 
foreach (KeyValuePair<string, object> kvp in mySettings) 
{ 
    PropertyInfo pi = mySettingsClass.GetType().GetProperty(kvp.key, BindingFlags.Public | BindingFlags.Instance); 
    if (pi != null) 
    { 
     pi.SetValue(mySettingsClass, kvp.Value, null); 
    } 
} 

當然,如果你正在讀回出一個DataReader,那麼你可以採取稍微不同的方式,避免使用反射(因爲DataReader的結構和目標結構對象是已知的)。在這種情況下使用反射速度較慢,但​​是將數據從一個項目統一映射到另一個項目的好方法 - 基本上,您需要使用source屬性,查看目標對象上是否存在目標屬性,然後如果是,則分配值。

+0

感謝您的僞代碼..我知道我可以用反射做到這一點,但我希望知道是否有其他選項,我可以做到這一點..我現在會堅持反思,看看它是如何工作的。 – Sam 2010-02-26 06:05:52

1

使用代碼生成來生成您的設置類。我已經完成了這個工作,並且工作得很好。這是我採取的方法:

  1. 在您自己設計的XML文件中定義您的設置。它需要至少定義設置名稱和類型。但是,如果您喜歡,可以添加其他內容:幫助字符串,默認值,驗證謂詞等。
  2. 使用t4讀取XML文件並生成Settings類。 (t4是內置於Visual Studio的代碼生成器。)

在這些種類的情況下,對靜態類型檢查的限制運行時,代碼生成通常很有用。代碼生成的一個好處是代碼是靜態類型的,所以你得到編譯時類型檢查,這當然是靜態類型的好處之一。

+0

我喜歡這個主意,但在我的情況下,我的所有設置都是由數據庫驅動的。 – Sam 2010-02-26 06:04:01

+0

@Sam,重點是從元數據生成C#代碼。元數據來自哪裏並不重要。您可以從表格的轉儲中生成C#,或者從設置的元數據定義的任何位置生成C#。 – 2010-02-26 07:45:57

2

添加這個答案(帖子是我知道的老) - 必須從@ slugster的答案中解決 - 這是最有前途的。

NameValueCollection nvc = HttpContext.Current.Request.Form; 
Settings mySettingsClass = new Settings(); 
foreach (string kvp in nvc.AllKeys) 
{ 
    PropertyInfo pi = model.GetType().GetProperty(kvp, BindingFlags.Public | BindingFlags.Instance); 
    if (pi != null) 
    { 
     pi.SetValue(model, nvc[kvp], null); 
    } 
} 

基本上唯一的區別是@slugster使用KeyValuePair,而不是NameValueCollection

1

這裏還有一個快捷方式,如果你在你的項目中Newtonsoft JSON庫 - 您可以使用它作爲一個翻譯機制。不知道這是否是非常出色的性能,但它非常簡潔和簡單。

假設「形式」是你的「的NameValueCollection」對象......

// convert to a string/string dictionary and remove anynulls that may have been passed in as a string "null" 
var formDictionary = form.AllKeys 
        .Where(p => form[p] != "null") 
        .ToDictionary(p => p, p => form[p]); 
string json = JsonConvert.SerializeObject(formDictionary); 
var myObject = JsonConvert.DeserializeObject<MyClass>(json); 
相關問題