2010-02-25 14 views
6

mam dane konfiguracyjne mojej aplikacji przechowywane w tabeli jak poniżej:Jak zautomatyzować namevaluecollection do ściśle napisanej klasy?

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

Moja klasa DataAccess powiedzieć Zwraca NameValueCollection/KeyValuePair ustawień zapisanych w tabeli.

Jaki byłby najlepszy sposób odwzorowania namevaluecollection/keyvaluepair na silnie typowaną klasę, taką jak ta poniżej, która ma właściwości o takiej samej nazwie jak w kolumnie SettingName.

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

Czy jest jakiś powód, dla którego trzeba użyć tego formatu dziwny zamiast używać app.config/web.config? –

Odpowiedz

2

Użyj refleksji. W pseudo kod:

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

Oczywiście, jeśli czytasz z powrotem z dataReader, wówczas można przyjąć nieco inne podejście i uniknąć przy użyciu odbicia (ponieważ struktura DataReader i struktura tarczy obiekt jest znany). Korzystanie z odbicia w tym przypadku jest wolniejsze, ale jest dobrym sposobem ogólnego mapowania danych z jednego elementu na inny - w zasadzie bierzesz właściwość źródłowa, sprawdzasz, czy właściwość docelowa istnieje w obiekcie docelowym, a następnie przypisujesz wartość, jeśli tak się dzieje.

+0

Dzięki za pseudo kod ... Wiem, że mogę to zrobić z refleksją, ale miałem nadzieję, że wiem, czy są inne opcje, jak mogę to zrobić. Będę trzymać się refleksji na teraz i zobacz, jak to działa. – Sam

0

Korzystanie System.Reflection nazw:

http://www.dotnetspider.com/resources/19232-Set-Property-value-dynamically-using-Reflection.aspx

uzyskać typ użyciu GetType() obiektu lub zrobić to dynamicznie użytku GetProperties uzyskać wszystkie właściwości z typem lub GetProperty do uzyskać jedną właściwość i wywołać wartość SetValue ze słownika.

To najprostszy sposób. Może istnieć jakiś obiekt odwzorowujący obiekty, który też może to zrobić.

HTH.

1

Użyj generowania kodu do wygenerowania swojej klasy Ustawienia. Zrobiłem to i działało bardzo dobrze. Oto podejście, które podjąłem:

  1. Określ swoje ustawienia w pliku XML własnego projektu. Musi zdefiniować co najmniej nazwy i typy ustawień. Ale możesz dodać inne rzeczy, jeśli chcesz: ciągi pomocy, wartości domyślne, predykaty sprawdzania poprawności itp.
  2. Użyj t4, aby odczytać plik XML i wygenerować swoją klasę (klasy) ustawień. (t4 to generator kodu wbudowany w Visual Studio.)

Generowanie kodu jest często przydatne w tego rodzaju przypadkach, w których napotykasz ograniczenia sprawdzania typu statycznego. Zaletą generowania kodu jest to, że kod jest statycznie wpisany, więc dostajesz sprawdzanie typu kompilacji, co oczywiście jest jedną z zalet pisania statycznego.

+0

Podoba mi się ten pomysł, ale w moim przypadku wszystkie moje ustawienia bazują na bazie danych. – Sam

+0

@Sam, celem jest generowanie kodu C# z metadanych. Nie ma znaczenia, skąd pochodzą te metadane. Możesz wygenerować C# ze zrzutu tabeli lub z dowolnego miejsca, gdzie zdefiniowane są metadane dla twoich ustawień. –

2

Dodanie tej odpowiedzi (post jest stary wiem) - musiałem przerobić odpowiedź @ slugster - to było najbardziej obiecujące.

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

W zasadzie jedyną różnicą jest @slugster użył KeyValuePair, zamiast NameValueCollection

1

Oto kolejny skrót, jeśli masz bibliotekę Newtonsoft JSON w projekcie - można go używać jako mechanizm translacji. Nie jestem pewien, czy to wszystko jest świetne pod względem wydajności, ale jest bardzo zwięzłe i proste ...

zakładamy „forma” jest Twój „NameValueCollection” obiekt ...

// 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); 
Powiązane problemy