´

Visual C# – Cómo tener un archivo de configuración más limpio

Articulo tomado de mi blog:

http://juank.black-byte.com/csharp-archivo-configuracion-limpio/

-----------------

o Como reducir el archivo de configuración usando múltiples archivos .config

Como programadores siempre tenemos que lidiar con archivos de configuración, en mi opinión una hermosa forma de deshacernos de complejidad innecesaria en el código y desde luego una manera muy cool de crear aplicaciones fléxibles.

Sin embargo en aplicaciones de tipo empresarial comenzamos a tener detestables problemas con estos archivos. El notable aumento de complejidad en su estructura se convierte en una bomba de tiempo para el mantenimiento de las aplicaciones, es común encontrase con archivos de configuración que se miden en cientos de lineas y a veces en miles.

Cómo tener un archivo de configuración más limpio?

Por fortuna existe un mecanismo muy útil, a continuación les muestro un archivo de configuración que si bien no es uno precisamente enorme, ya comienza a mostrar problemasde legibilidad, en esta ocasión generados por la configuración de Unity Application Block , hablaremos de el en otro momento.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
      <typeAliases>
        <!-- Lifetime manager types -->
        <typeAlias alias="singleton"
             type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
                   Microsoft.Practices.Unity" />
        <typeAlias alias="external"
             type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,
                   Microsoft.Practices.Unity" />
        <!-- User-defined Lifetime manager types -->
        <typeAlias alias="web_session"
            type="Traversal.Utilities.Web.WebSessionLifetimeManager,
                   Traversal" />
        <!-- Tipos para Domain.Core -->
        <typeAlias alias="IDataContextWrapper"  type="Domain.Core.Data.IDataContextWrapper`1, Domain.Core" />
        <typeAlias alias="IParameterManager"    type="Domain.Core.Repositories.IParameterManager, Domain.Core" />
        <typeAlias alias="ILocalizationManager" type="Domain.Core.Repositories.ILocalizationManager, Domain.Core" />
 
        <typeAlias alias="ContextWrapperSTE"    type="Domain.Core.Data.ContextWrapperSTE`1, Domain.Core" />
        <typeAlias alias="ContextWrapperEF"     type="Domain.Core.Data.ContextWrapperEF`1, Domain.Core" />
        <typeAlias alias="ParameterManager"     type="Domain.Core.Repositories.ParameterManager, Domain.Core" />
        <typeAlias alias="LocalizationManager"  type="Domain.Core.Repositories.LocalizationManager, Domain.Core" />
 
        <!-- Tipos para oplkjsdfkpwe.Core -->
        <typeAlias alias="IEnteManager"          type="Domain.wsldckm.Repositories.IEnteManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="IEquipoManager"        type="Domain.wsldckm.Repositories.IEquipoManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="IEstadioManager"       type="Domain.wsldckm.Repositories.IEstadioManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="IEventoManager"        type="Domain.wsldckm.Repositories.IEventoManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="IPartidoManager"       type="Domain.wsldckm.Repositories.IPartidoManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="ITagManager"           type="Domain.wsldckm.Repositories.ITagManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="ITipoFormacionManager" type="Domain.wsldckm.Repositories.ITipoFormacionManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="ITorneoEtapaManager"   type="Domain.wsldckm.Repositories.ITorneoEtapaManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="ITorneoNominaManager"  type="Domain.wsldckm.Repositories.ITorneoNominaManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="ITorneoManager"        type="Domain.wsldckm.Repositories.ITorneoManager, Domain.oplkjsdfkpwe" />
 
        <typeAlias alias="EnteManager"           type="Domain.wsldckm.Repositories.EnteManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="EquipoManager"         type="Domain.wsldckm.Repositories.EquipoManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="EstadioManager"        type="Domain.wsldckm.Repositories.EstadioManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="EventoManager"         type="Domain.wsldckm.Repositories.EventoManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="PartidoManager"        type="Domain.wsldckm.Repositories.PartidoManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="TagManager"            type="Domain.wsldckm.Repositories.TagManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="TipoFormacionManager"  type="Domain.wsldckm.Repositories.TipoFormacionManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="TorneoEtapaManager"    type="Domain.wsldckm.Repositories.TorneoEtapaManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="TorneoNominaManager"   type="Domain.wsldckm.Repositories.TorneoNominaManager, Domain.oplkjsdfkpwe" />
        <typeAlias alias="TorneoManager"         type="Domain.wsldckm.Repositories.TorneoManager, Domain.oplkjsdfkpwe" />
      </typeAliases>
      <containers>
        <container name="WebContainer">
          <types>
            <!-- Tipos para Domain.Core -->
            <type type="IParameterManager" mapTo="ParameterManager" />
            <type type="ILocalizationManager" mapTo="LocalizationManager" />
            <type type="IDataContextWrapper" mapTo="ContextWrapperEF">
              <lifetime type="web_session" />
            </type>
            <!--
              <type type="IDataContextWrapper" mapTo="ContextWrapperSTE">
                <lifetime type="web_session" />
              </type>-->
            <!-- Tipos para oplkjsdfkpwe.Core -->
            <type type="IEnteManager"           mapTo="EnteManager"         />
            <type type="IEquipoManager"         mapTo="EquipoManager"       />
            <type type="IEstadioManager"        mapTo="EstadioManager"      />
            <type type="IEventoManager"         mapTo="EventoManager"       />
            <type type="IPartidoManager"        mapTo="PartidoManager"      />
            <type type="ITagManager"            mapTo="TagManager"          />
            <type type="ITipoFormacionManager"  mapTo="TipoFormacionManager"/>
            <type type="ITorneoEtapaManager"    mapTo="TorneoEtapaManager"  />
            <type type="ITorneoNominaManager"   mapTo="TorneoNominaManager" />
            <type type="ITorneoManager"         mapTo="TorneoManager"       />
          </types>
        </container>
 
        <container name="StandAloneContainer">
          <types>
            <type type="IParameterManager" mapTo="ParameterManager" />
            <type type="ILocalizationManager" mapTo="LocalizationManager" />
            <type type="IDataContextWrapper"  mapTo="ContextWrapperEF" >
              <lifetime type="singleton" />
            </type>
          </types>
        </container>
      </containers>
    </unity>
 
  <appSettings>
    <add key="UnitySection" value="unity"/>
    <add key="UnityContainer" value="WebContainer"/>
  </appSettings>
  <connectionStrings>
    <add name="CoreContext"
    connectionString="metadata=res://Data.Core/DataCoreModel.csdl|res://*/DataCoreModel.ssdl|res://*/DataCoreModel.msl;
                        provider=System.Data.SqlClient;provider connection string=&quot;
                        data source=reveverv.database.windows.net;initial catalog=rrvr;
                        persist security info=True;user id=erverver;password=erverver;
                        multipleactiveresultsets=True;application name=EntityFramework&quot;"
                        providerName="System.Data.EntityClient" />
    <add name="wdsefreContext" connectionString="metadata=res://Data.Core/erverModel.csdl|res://*/ervercvModel.ssdl|res://*/erverv.msl;
                                provider=System.Data.SqlClient;provider connection string=&quot;
                                data source=erfververv.database.windows.net;initial catalog=rverv;
                                persist security info=True;user id=erververv;password=dfvdfv;
                                multipleactiveresultsets=True;application name=EntityFramework&quot;"
                                providerName="System.Data.EntityClient" />
 
    <add name="ApplicationServices"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
 
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>
 
    <membership>
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
             applicationName="/" />
      </providers>
    </membership>
 
    <profile>
      <providers>
        <clear/>
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
      </providers>
    </profile>
 
    <roleManager enabled="false">
      <providers>
        <clear/>
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>
 
  </system.web>
 
  <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
 
</configuration>

Toda sección posee un atributo configSource en el cual se puede indicar la ruta donde se encuentra definido el XML, asi que podemos extraer toda la sección de Unity en un archivo Unity.config , incluyendo la etiqueta y sus atributos, y el archivo de configuración quedaria de la siguiente forma, bastante más legible y manteniendo toda su funcionalidad.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity configSource="Unity.config"  />
 
  <appSettings>
    <add key="UnitySection" value="unity"/>
    <add key="UnityContainer" value="WebContainer"/>
  </appSettings>
  <connectionStrings>
    <add name="CoreContext"
    connectionString="metadata=res://Data.Core/DataCoreModel.csdl|res://*/DataCoreModel.ssdl|res://*/DataCoreModel.msl;
                        provider=System.Data.SqlClient;provider connection string=&quot;
                        data source=reveverv.database.windows.net;initial catalog=rrvr;
                        persist security info=True;user id=erverver;password=erverver;
                        multipleactiveresultsets=True;application name=EntityFramework&quot;"
                        providerName="System.Data.EntityClient" />
    <add name="wdsefreContext" connectionString="metadata=res://Data.Core/erverModel.csdl|res://*/ervercvModel.ssdl|res://*/erverv.msl;
                                provider=System.Data.SqlClient;provider connection string=&quot;
                                data source=erfververv.database.windows.net;initial catalog=rverv;
                                persist security info=True;user id=erververv;password=dfvdfv;
                                multipleactiveresultsets=True;application name=EntityFramework&quot;"
                                providerName="System.Data.EntityClient" />
 
    <add name="ApplicationServices"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
 
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>
 
    <membership>
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
             applicationName="/" />
      </providers>
    </membership>
 
    <profile>
      <providers>
        <clear/>
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
      </providers>
    </profile>
 
    <roleManager enabled="false">
      <providers>
        <clear/>
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>
 
  </system.web>
 
  <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
 
</configuration>

Y desde luego ese mismo atributo lo podemos usar en todas las secciones que superen un tamaño pequeño.

Enjoy it!

Leave a Comment

(required) 

(required) 

(optional)
 

(required) 

If you can't read this number refresh your screen
Enter the numbers above: