2009-01-09 10 views
53

¿Alguien sabe de alguna buena herramienta/utilidades para administrar archivos Web.Config entre diferentes entornos de compilación/despliegue?Administración de archivos complejos Web.Config entre entornos de implementación

Por ejemplo, tengo un proyecto WCF que, en desarrollo, no quiero habilitar SSL, pero sí quiero que esté habilitado en producción. Quiero diferentes configuraciones de registro, diferentes cadenas de conexión de DB, manejo de errores diferentes, diferentes rutas de archivos ... Incluso algunos enlaces de framework de Unity diferentes (wire up mocks para pruebas unitarias en lugar de los objetos reales para implementación).

Mantener las copias individuales del Web.Config es un problema, porque agregar un nuevo servicio web significa editar varios archivos y mantenerlos sincronizados.

También he notado que si arruinas demasiado el Web.Config a mano, Visual Studio se ahogará si tratas de usar el asistente "agregar elemento" para, digamos, agregar un nuevo servicio web para WCF, ya que tiene que modificar Web.Config para agregar el punto final, y nd no puede analizarlo más. Por lo tanto, debo tener cuidado de no invalidar el Web.Config existente.

También pensé en usar solo regex para hacer reemplazos y simplemente construir un nuevo Web.Config en un comando previo a la compilación. Esa parece ser la mejor opción hasta ahora ...

¿Alguna otra idea? Parece que esto debería ser un problema muy común, ya que el Web.Config probablemente nunca debería ser el mismo entre las implementaciones de desarrollo y producción.


Actualización:

decidí escribir una aplicación de consola rápida que se llevará a todos los archivos XML en un directorio determinado y fusionarlas en una sola, y sólo incluir ciertos archivos basado en el nombre.

Así que puedo hacer en un directorio:

WebConfig_All

<configuration> 
    <configSections> 
    ... 
    </configSections> 
    <system.web> 
    ... 
    </system.web> 
</configuration> 

connectionStrings_Debug

<configuration> 
    <connectionStrings> 
    <add name="connstr" connectionString="...dev..." /> 
    </connectionStrings> 
</configuration> 

connectionStrings_Release

<configuration> 
    <connectionStrings> 
    <add name="connstr" connectionString="...prod..." /> 
    </connectionStrings> 
</configuration> 

A continuación, ejecute mi herramienta de línea de comandos, y pasan en la configuración (depuración, liberación, a medida ...) y va a fusionar todos los archivos que terminan en _All" or _ < configuración `>.

Así que ahora tengo el 80% de mi Web.Config en un solo archivo WebConfig_All, y el 20% de cosas personalizadas en archivos separados por configuración de compilación. Luego puedo ejecutar mi herramienta de línea de comando como una tarea previa a la construcción en VisualStudio, o desde NAnt, o donde yo quiera ...

También hice mi lógica de combinación de XML suficientemente bueno para manejar cosas como:

<x> 
    <y a="1"> 
    <z a="1"/> 
    </y> 
</x> 

fusión con

<x> 
    <y a="1"> 
    <z a="2"/> 
    </y> 
    <y a="2"/> 
</x> 

resultados en:

<x> 
    <y a="1"> 
    <z a="1"/> 
    <z a="2"/> 
    </y> 
    <y a="2"/> 
</x> 

Verse bien hasta ahora .. . :)


Seguimiento:

Este tema es un poco viejo ahora, así que quería señalar que VisualStudio 2010 tiene una función para hacer transformaciones web.config incorporada: http://msdn.microsoft.com/en-us/vstudio/Video/ff801895

Por supuesto, en el típico La moda de Microsoft de implementar solo cualquier función el 50% del camino, solo funciona para proyectos web que usan despliegue web. Hay un plugin para permitir transformaciones en otros proyectos, que se encuentra aquí: http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx

También es posible usar una herramienta como BuildMaster para gestionar archivos de configuración (junto con las formaciones, pruebas, scripts de base de datos, etc ...)

Respuesta

19

Dividimos a cabo todos los ajustes específicos de la región en emabrgo propia archivo de configuración. Debajo de la raíz de la aplicación web, creamos una carpeta de configuración y colocamos allí la configuración específica de la región. Entonces, cualquier archivo que esté viviendo bajo la raíz de config será recogido.

nuestro web.config se ve algo como:

. 
. 
. 
<appSettings configSource="config\appSettings.config"/> 
<nlog configSource="config\nlog.config"/> 
<applicationSettings> 
    <MyApp.UI.Properties.Settings configSource="config\Settings.APGUI.config"/> 
    <MyApp.BusinessServices.Properties.Settings configSource="config\Settings.Business.config"/> 
    <MyApp.Auditing.Properties.Settings configSource="config\Settings.Auditing.config"/> 
</applicationSettings> 
. 
. 
. 

Así que si estamos desplegando a la zona de liberación de la herramienta de construcción sólo tendremos una acción para reemplazar los archivos en la raíz de configuración con los archivos de la carpeta de región apropiada. La estructura de archivos se ve algo como:

añadido: Esta es la forma en la estructura de control de código fuente se ve, la aplicación desplegada sólo tendría el directorio config sin subcarpetas o supuesto

\Root 
    web.config  
    \Config  
     appsettings.config  
     services.config  
     logging.config  
     \release  
      appsettings.config  
      services.config  
      logging.config  
     \debug 
      appsettings.config  
      services.config  
      logging.config 

Es bastante limpio y apoyado mediante cualquier herramienta de compilación automatizada (copiando/reemplazando archivos).El lado agradable es que los desarrolladores pueden crear diferentes sabores y mantenerlos bajo el control de la fuente sin afectar las configuraciones "reales".

+0

Me gusta el uso del atributo configSource. Quizás pueda incorporar eso de alguna manera. Sería bueno si visualstudio pudiera traducirlos automáticamente en el momento de la construcción y usar los marcos de las herramientas de ejecución ... para que pueda especificar "configSource = Config \ $ (ConfigurationName) \ My.Config" – CodingWithSpike

+0

¡Esta es una GRAN solución! En donde estoy, los desarrolladores usan Visual Studio para el trabajo de desarrollo, luego tenemos una máquina de creación usando CruiseControl y NAnt que crea las diferentes versiones (prueba, etapa, producción, ...). Esto es perfecto para nosotros, porque podríamos simplemente crear una tarea NAnt para copiar los archivos de configuración apropiados en función de la versión que se está creando (o podría usar MSBuild o Visual Studio para hacer lo mismo si se adapta mejor a su entorno). –

1

Tradicionalmente he usado los múltiples web.configs como mencionaste. Puede ser un problema, pero se ve mitigado por herramientas de comparación de archivos como BeyoneComapare2 o KDIff ...

+1

I love Beyond Compare! Una de mis mejores 5 herramientas favoritas. – CodingWithSpike

7

Puede usar Build Events para administrar sus configuraciones web. Hanselman tiene un buen artículo al respecto.

Básicamente tiene todos sus diferentes contenidos web en la solución y luego crea (algunos) nuevos tipos de compilación. Dependiendo del tipo de compilación que ejecute, ¡web.config se copia sobre el referido!

+0

También me gusta esta configuración utilizando un evento de preconstrucción en Visual Studio para sobrescribir el web.config con la configuración web.config correcta (.debug, .release, .deploy). Aunque requiere que mantenga varios archivos de configuración, es una configuración simple y limpia. Por cierto es "Hanselman" y no "Hanselmen". – PropellerHead

+0

Se arregló el error ortográfico gracias! – cgreeno

+0

exactamente lo que escribí @ al mismo tiempo :) – Cohen

2

Me gusta usar una tarea de compilación en automate cambiando el archivo de configuración para el entorno deseado.

0

molestia:

I mencionado mi pequeña aplicación de línea de cmd para fusionar documentos XML en mi primera actualización ... Bueno, para hacerlo sólo tiene que utilizar XmlDocument, y, finalmente, acaba .Save() a un FileStream.

Desafortunadamente, los nodos no están realmente en ningún orden en particular, y al parecer, .NET requiere los <configSections> elementos sean la primera hija del documento.

Pensé que todas estas herramientas de lujo se suponía que para hacer la vida de programación más fácil?

4

puedo utilizar esta herramienta: xmlpreprocess

mantenemos archivos separados 'propiedad' para cada entorno que se fusionó en el script de implementación.

2

Utilizamos etiquetas en nuestros archivos de configuración, que se reemplazan en tiempo de compilación para reflejar el entorno de despliegue previsto. Me he inspirado en Lavablast blog

Es bueno tener solo un archivo de configuración de plantilla para administrar.

El inconveniente es que no puede tener fácilmente "secciones" personalizadas.

7

desea que la tarea XmlMassUpdate en MSBuildCommunityTasks (hace lo que estamos tratando de hacer con su aplicación de consola XML)

http://msbuildtasks.tigris.org/

utilizar de esta manera

<XmlMassUpdate Condition=" '@(ConfigTemplateFile)'!='' And '@(ConfigSubstitutionsFile)'!=''" 
    ContentFile="@(ConfigTemplateFile)" 
    SubstitutionsFile="@(ConfigSubstitutionsFile)" 
    MergedFile="@(ConfigFile)" 
    ContentRoot="/configuration" 
    SubstitutionsRoot="/configuration/substitutions/$(Configuration)"/> 
0

Mis favoritos dos maneras de tratar con esto son:

A. Mantener la configuración en la máquina de destino * - En Azure, por ejemplo, puede configurar la configuración de la aplicación a nd cadenas de conexión que anularán los valores en web.config. (* - o definición de la máquina de destino si la configuración de su infraestructura es dinámica).

B. Haga que la herramienta de compilación/implementación (TeamCity, Octopus Deploy, etc., VS Team Services) incorpore los valores específicos del entorno como parte de la compilación y/o implementación. Las herramientas modernas admiten el cifrado de configuraciones confidenciales.

2

Pregunta anterior, pero dado que tiene un alto rango en la búsqueda de Google, pensé que era una buena idea agregar , que has been available since VS2010. Con esta herramienta, puede tener diferentes archivos web.config para diferentes compilaciones (depuración/versión)

Aquí hay un breve resumen sobre cómo tener dos cadenas de conexiones: una para desarrollo (modo Depuración) y otra para producción (Versión modo):

1- Configure su cadena de conexión de desarrollo en el archivo web.config. Debe ser similar a esto:

<connectionStrings> 
    <add name="myConnectionString" connectionString="Data Source=TestDBServer; (etc...)" /> 
    </connectionStrings> 

2- Expandir su archivo web.config y web.release abierta.config

web.config

3- Utilice el Replace function para reemplazar la cadena de conexión con el otro para que desea para la producción. Puede utilizar xdt:Locator="Match(name)" atributo para que coincidan con el nombre de la cadena de conexión (myConnectionString) en este ejemplo:

<connectionStrings> 
    <add name="myConnectionString" xdt:Transform="Replace" xdt:Locator="Match(name)" 
     connectionString="Data Source=ProdDBServer; (etc...)" /> 
    </connectionStrings> 

4- Vista previa de la transformación del archivo web.config que se utilizará durante la liberación de construcción haciendo clic derecho en el archivo web.release.config y seleccionando Vista previa Transformar.

enter image description here

Cuestiones relacionadas