Config ClassW poprzedniej pracy zgodnie z zalecanym wzorcem tworzyliśmy klasę konfiguracyjną, której właściwości odpowiadały wartościom słownikowym  w pliku konfiguracyjnym.  Taka klasa rozwiązuje problem z magicznymi stringami i plikami konfiguracyjnymi. Wtedy  ja taką klasę  pisałem ręcznie co jest czystą głupotą ponieważ można napisać template T4 który zrobi to za nas.

Wzór jest prosty patrzymy jakie klucze,wartości oraz “connectionString” są zawarte w pliku konfiguracyjnym i piszemy do nich specyficzne właściwości.

Podstawy T4 opisałem już wcześniej i nie widzę sensu się powtarzać.

Oto przykładowy plik konfiguracyjny. Zawiera on jedną wartość słownikową zdefiniowaną w appSettings, jak i jeden “connectionString”.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <connectionStrings >
    <add name="ConnectionSQL" connectionString="
         Server=myServerAddress;Database=myDataBase;User 
         Id=myUsername;Password=myPassword;"/>
  </connectionStrings>
  <appSettings>
    <add key="Klucz" value="wartość"/>
  </appSettings>
</configuration>

Do odczytania pliku konfiguracyjnego przyda się LINQ do XML, jak i oczywiście klasy pomocnicze z przestrzeni nazw “System.Configuration”.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly Name="System.Configuration" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ assembly name="System.Net" #>
<#@ assembly name="System" #>
<#@ import namespace="System.Configuration" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Net" #>
<#@ import namespace="System.Xml.Linq" #>

Oto kod T4, który przeskanuje plik konfiguracyjny i wygeneruje odpowiednie właściwości do klasy “Configos”. Ten kod generujący nie jest ,aż tak bardzo skomplikowany.

using System.Configuration;

namespace T4Config
{
    public partial class Configos
    {
        <#
        var xDocument = XDocument.Load(
        @"D:\PanNiebieski\Documents\Visual Studio 2012\Projects\T4Config\App.config");
        var results =   xDocument.Descendants("appSettings");
        const string key = "key";
        const string name = "name";

        foreach (var xElement in results.Descendants())
        {#>
        public string <#= xElement.Attribute(key).Value#>
        {
            get 
            {
                return ConfigurationManager.AppSettings
                [<#= string.Format("{0}{1}{2}","\"" , xElement.Attribute(key).Value, "\"")#>];
            }
        }
        <#}#>
        <#
        var connectionStrings = xDocument.Descendants("connectionStrings");
        foreach(var connString in connectionStrings.Descendants())
        {#>
        public string <#= connString.Attribute(name).Value#>
        {
            get 
            {
                return 
                ConfigurationManager.ConnectionStrings
                [<#= string.Format("{0}{1}{2}","\"" , connString.Attribute(name).Value, "\"")#>]
                .ConnectionString;
            }
        }
        <#}    #>
    }
}

Oto wygenerowana klasa. Teraz dostęp do potrzebnych informacji w pliku konfiguracyjnym nie wymaga magicznych stringów.

using System.Configuration;

namespace T4Config
{
    public partial class Confios
    {
        public string Klucz
        {
            get
            {
                return ConfigurationManager.AppSettings
                ["Klucz"];
            }
        }
        public string ConnectionSQL
        {
            get
            {
                return
                ConfigurationManager.ConnectionStrings
                ["ConnectionSQL"]
                .ConnectionString;
            }
        }
    }
}

Ten kod T4 nie jest jednak doskonały. Czy ktoś wymyślił już lepsze rozwiązanie?

Sprawdzimy co oferuje NuGet pod szukanym słowem T4.

NuGet

Jak widać w NuGet istnieje gotowa paczka “T4Configuration”, która zrobi dokładnie to samo co ja przed chwilą.

image

Nie ma sensu umieszczać kodu tej paczki ,ale jest on bardziej rozbudowany i nie wymaga dokładnego określenia położenia pliku konfiguracyjnego. Czyli te rozwiązanie jest lepsze.

T4Configuration