70-536: Configuring Applications

Poniższy artykuł pochodzi z serii Przygotowań do egzaminu 70-536.

Przechowywanie ustawień aplikacji, czy ustawień połączenia z bazą danych (ang. connection string), to częsty wymóg. Zapisywanie ich “na sztywno” w kodzie aplikacji jest złą praktyką. Na szczęście .NET Framework udostępnia nam zestaw klas, które ułatwiają przechowywanie tych ustawień w specjalnych plikach XML. Mamy dwa główne typy takich plików:

  1. Globalny plik Machine.config, który jest wspólny dla wszystkich aplikacji korzystających z .NET Framework,
  2. Plik <Application_Name>.config skojarzony z konkretną aplikacją.

Zapisywanie ustawień

W naszym projekcie należy dodać referencję (opcja Add Reference…), do biblioteki System.Configuration, która znajduje się w zakładce .NET. Następni należy dodać odpowiednią dyrektywę using:

   1: using System.Configuration;

Przykładowy program:

   1: Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
   2: config.AppSettings.Settings.Add("MyKey", "MyValue");
   3: // Zapisz plik konfiguracyjny
   4: config.Save(ConfigurationSaveMode.Modified);
  • Wywołanie ConfigurationManager.OpenExeConfiguration utworzy instancję klasy Configuration,
  • Configuration.Add doda klucz i wartość do ustawień,
  • Wywołanie Configuration.Save zapisze ustawienia do pliku .config.

Uwaga: Po zbudowaniu aplikacji i uruchomieniu z poziomu Visual Studio, plik ustawień nie zostanie utworzony. VS nie korzysta ze standardowego pliku .config. Zbudowany program należy odpalić ręcznie z katalogu projektu.

Wygenerowany plik XML ustawień wygląda nastęująco:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <configuration>
   3:     <appSettings>
   4:         <add key="MyKey" value="MyValue" />
   5:     </appSettings>
   6: </configuration>

Plik ten możemy zmodyfikować samodzielnie, np. za pomocą programu Notatnik. Wewnątrz znacznika appSettings dodajmy nowe ustawienie:

   1: <add key="Ala" value="ma kota" />

Zadanie: Zakładamy, że nasz program zawiera poniższy kod. Który z kluczy zostanie zapisany?

   1: ConfigurationManager.AppSettings.Set("Key1", "Value1");
   2: Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
   3: config.AppSettings.Settings.Add("Key2", "Value2");
   4: config.Save((ConfigurationSaveMode.Modified));
   5: config.AppSettings.Settings.Add("Key3", "Value3");

Zapisany zostanie jedynie Key2, ponieważ po jego dodaniu wywołana jest metoda config.Save. Dla pierwszego klucz (Key1) wywołanie ConfigurationManager.AppSettings.Set nie zapisze ustawień na stałe. Po kluczu nr 3 (Key3) nie ma wywołania metody Save, więc ustawienie nie zostanie zapisane.

Odczyt ustawień

Ustawienia aplikacji możemy odczytać korzystając ze statycznej kolekcji ConfigurationManager.AppSettings. Zakładając, że chcemy wypisać wszystkie ustawienia:

   1: for (int i = 0; i < ConfigurationManager.AppSettings.Count; i++)
   2: {
   3:     Console.WriteLine("{0}: {1}",
   4:     ConfigurationManager.AppSettings.AllKeys[i],
   5:     ConfigurationManager.AppSettings[i]);
   6: }

Wypisze:

   1: MyKey: MyValue
   2: Ala: ma kota

Możemy także wyciągnąć wartość konkretnego ustawienia podając klucz:

   1: Console.WriteLine(ConfigurationManager.AppSettings["Ala"]); // ma kota

Przechowywanie ustawień połączenia z bazą danych

Connection string definiuje połączenie naszej aplikacji z bazą danych. Przechowywanie tych ustawień w pliku pozwala łatwo nam łatwo je zmienić w przypadku zmiany parametrów połączenia.

Dodajmy przykładowe ustawienie do naszego pliku .config (w obrębie znacznika appSettings):

   1: <connectionStrings>
   2: <add name="LocalSqlServer"
   3:   connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
   4:   providerName="System.Data.SqlClient" />
   5: </connectionStrings>

Mamy skonfigurowany connection string pod kluczem LocalSqlServer, chcemy dostać się do niego z poziomu naszego kodu.W kolekcji ConfigurationManager.ConnectionStrings podajemy klucz, aby pobrać ustawienia połączenia.

   1: Console.WriteLine(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);

Wypisanie jest oczywiście najprostszym przykładem. Jeśli mielibyśmy więcej połączeń możemy wypisać informacje o nich wszystkich:

   1: ConnectionStringSettingsCollection connections = ConfigurationManager.ConnectionStrings;
   2: foreach (ConnectionStringSettings connection in connections)
   3: {
   4:   Console.WriteLine("Name: {0}", connection.Name);
   5:   Console.WriteLine("Connection string: {0}",
   6:   connection.ConnectionString);
   7:   Console.WriteLine("Provider: {0}", connection.ProviderName);
   8:   Console.WriteLine("Source: {0}",
   9:   connection.ElementInformation.Source);
  10: }

Ustawienia maszyny (Machine Configuration Settings)

Zwykle nie ma takiej potrzeby, ale gdybyśmy chcieli dostać się do globalnych ustawień należy wywołać metodę ConfigurationManager.OpenMachineConfiguration. W wyniku jej wywołania otrzymamy obiekt Configuration, który zawiera sekcje z różnymi ustawieniami.

   1: Configuration machineSettings = ConfigurationManager.OpenMachineConfiguration();
   2: ProtectedConfigurationSection pcs = (ProtectedConfigurationSection)machineSettings.GetSection("configProtectedData");
   3: Console.WriteLine(pcs.DefaultProvider);
   4: Console.WriteLine(pcs.Providers["DataProtectionConfigurationProvider"].Parameters["description"]);

Powyższy przykład:

  1. Pobiera ustawienia maszyny,
  2. Pobiera konfigurację sekcji configProtectedData, rzutuje go na obiekt ProtectedConfigurationSection,
  3. Wyświetl parametry zwróconego obiektu,
  4. Wyświetl parametr wybranego providera.

Tworzenie własnych sekcji

Własne sekcje możemy utworzyć na dwa sposoby:

  • Implementacja interfejsu IConfigurationSectionHandler,
  • Dziedziczenie po ConfigurationSection.

Pierwsza metoda oznaczona jest jako przestarzała. Dziedziczenie po ConfigurationSection jest preferowaną metodą tworzenia własnych sekcji w .NET Framework, począwszy od wersji 2.0. Poniżej przykład z Training Kit:

   1: namespace ConfigApp
   2: {
   3:     public class MyHandler : ConfigurationSection
   4:     {
   5:         public MyHandler()
   6:         {
   7:         }
   8:         [ConfigurationProperty("lastUser", DefaultValue = "User",
   9:         IsRequired = true)]
  10:         [StringValidator(InvalidCharacters =
  11:         "~!@#$%^&*()[]{}/;'\"|\\",
  12:         MinLength = 1, MaxLength = 60)]
  13:         public string LastUser
  14:         {
  15:             get
  16:             {
  17:                 return (string)this["lastUser"];
  18:             }
  19:             set
  20:             {
  21:                 this["lastUser"] = value;
  22:             }
  23:         }
  24:         [ConfigurationProperty("lastNumber")]
  25:         public int LastNumber
  26:         {
  27:             get
  28:             {
  29:                 return (int)this["lastNumber"];
  30:             }
  31:             set
  32:             {
  33:                 this["lastNumber"] = value;
  34:             }
  35:         }
  36:     }
  37:     class Program
  38:     {
  39:         static void Main(string[] args)
  40:         {
  41:             MyHandler settings =
  42:             (MyHandler)ConfigurationManager.GetSection(
  43:             "customSettings");
  44:             Console.WriteLine(settings.LastUser);
  45:             Console.WriteLine(settings.LastNumber);
  46:         }
  47:     }
  48: }

Zadanie: Chcemy przeczytać ustawienia z sekcji pliku .config aplikacji. Co możemy zrobić?

  • Utworzyć klasę, która dziedziczy po ConfigurationSection – zalecana metoda,
  • Zdefiniować sekcję <configSection> w pliku .config aplikacji,
  • Utworzyć własną sekcję w sekcji <configuration> pliku .config aplikacji.

Istnieje jeszcze opcja dziedziczenia po interfejsie IConfigurationSectionHandler. Nie jest to jednak metoda zalecana.

Kolejny artykuł z serii to 70-536:Configuring the .NET Framework

Tagi: ,

Pingbacks and trackbacks (2)+

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Eastgroup.pl na facebooku