c# - usuario - archivos específicos del desarrollador app.config/web.config en Visual Studio
my.settings c# (9)
Tenemos varios proyectos .NET donde almacenamos ciertas configuraciones en archivos de configuración. Ahora cada desarrollador tendrá sus propios archivos de configuración que difieren un poco (diferentes cadenas de conexión para conectarse a la base de datos local, diferentes puntos finales WCF, etc.)
Por el momento, tendemos a consultar los archivos de la aplicación / web.config y modificarlos para satisfacer nuestras necesidades. Esto genera muchos problemas, ya que de vez en cuando alguien verifica su propia configuración o pierde la configuración personalizada al obtener la última versión de tfs.
Mi pregunta es: ¿cómo lidias con situaciones como esta? ¿O no tienes este problema en absoluto?
¿Qué hay de ignorar el archivo, por lo que nunca se registra? Me he encontrado con un problema similar y he agregado web.config a la lista de ignorar en Subversion.
En TFS, sin embargo, es un poco más difícil, consulte esta publicación sobre cómo hacerlo.
Aquí una solución para archivos web.config y Visual Studio 2010:
1) Edite manualmente el archivo .csproj de su aplicación web para agregar un objetivo de AfterBuild
como este:
<Project>
...
<Target Name="AfterBuild">
<Copy SourceFiles="web.config" DestinationFiles="obj/$(Configuration)/tempweb.config" />
<TransformXml Source="obj/$(Configuration)/tempweb.config"
Transform="web.$(USERNAME).config"
Destination="obj/$(Configuration)/tempweb2.config" />
<ReadLinesFromFile File="obj/$(Configuration)/tempweb2.config"><Output TaskParameter="Lines" ItemName="TransformedWebConfig"/></ReadLinesFromFile>
<ReadLinesFromFile File="web.config"><Output TaskParameter="Lines" ItemName="UnTransformedWebConfig"/></ReadLinesFromFile>
<Copy Condition=" @(UnTransformedWebConfig) != @(TransformedWebConfig) " SourceFiles="obj/$(Configuration)/tempweb2.config" DestinationFiles="web.config" OverwriteReadOnlyFiles="True" />
</Target>
</Project>
Este objetivo transformará el archivo Web.config correspondiente al desarrollador actual que inició sesión - de ahí la variable $(USERNAME)
-, con el archivo correspondiente creado en 1). Reemplazará el Web.config local solo si el contenido ha cambiado (para evitar el reinicio) en cada compilación, incluso si el Web.config local está controlado por la fuente, por eso existe el OverwriteReadOnlyFiles
establecido en True. Este punto, de hecho, es discutible.
2) Cree un archivo llamado Web.[developer windows login].config
de Web.[developer windows login].config
para cada desarrollador en el proyecto. (por ejemplo, en las siguientes capturas de pantalla tengo dos desarrolladores llamados smo y smo2):
Estos archivos (1 por desarrollador) pueden / deben ser controlados por la fuente. No deben marcarse como dependientes del Web.config principal porque deseamos poder verificarlos individualmente.
Cada uno de estos archivos representa una transformación para aplicar al archivo principal Web.Config. La sintaxis de transformación se describe aquí: Web.config Sintaxis de transformación para la implementación de proyectos de aplicaciones web . Reutilizamos esta genial tarea de transformación de archivos Xml que viene de fábrica con Visual Studio. El objetivo de esta tarea es fusionar elementos y atributos Xml en lugar de sobrescribir todo el archivo.
Por ejemplo, aquí hay un ejemplo de web.[dev login].config
que cambia una cadena de conexión llamada ''MyDB'', independientemente del resto del archivo Web.config:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</connectionStrings>
</configuration>
Ahora, esta solución no es perfecta porque:
- después de construir, los desarrolladores pueden tener un Web.Config diferente localmente que en el sistema de control de origen
- pueden tener que forzar la escritura local al obtener un nuevo Web.Config del sistema de control de origen
- los desarrolladores no deberían consultar / en el sitio web principal.config. Debería reservarse para pocas personas.
Pero al menos, solo debe mantener un archivo web principal único de configuración más uno de transformación por desarrollador.
Se podría tomar un enfoque similar para los archivos de App.config (no para la web) pero no proporcioné más detalles.
En tu Web.config utiliza el origen de otros archivos
<configuration>
<connectionStrings configSource="ConnectionStrings.config" />
...
</configuration>
Mantenga el archivo web.config en control de versiones y no lo haga para ConnectionStrings.config. Ahora todos los desarrolladores tienen un archivo para la cadena de conexión.
Puede hacer esto para todas las configuraciones que dependen del local.
Estamos utilizando machine.config para evitar tener diferencias en web.config entre los entornos.
Ignore los archivos y tenga Commom_Web.Config y Common_App.Config. Utilizar un servidor de compilación de integración continua con tareas de compilación que cambian el nombre de estos dos a nombres normales para que el servidor de compilación pueda hacer su trabajo.
Suponiendo que está utilizando Visual Studio, ¿por qué no utiliza diferentes configuraciones de solución? Por ejemplo: puede tener una configuración de depuración que utiliza Web.config.debug y una configuración de liberación que utiliza Web.config.release. Web.config.debug debería tener algo como
<appSettings file="C:/Standard_Path_To_Configs/Standard_Name_For_Config.config">
con el archivo Standard_Name_For_Config.config que muestra todas las configuraciones personales del desarrollador, mientras que Web.config.release siempre tiene la configuración de producción. Puede almacenar las configuraciones predeterminadas en alguna carpeta controlada por fuente y hacer que un nuevo usuario las tome desde allí.
Tenemos el mismo problema y lo que estamos haciendo es
- Compruebe en web.config con testserver / production values
- El desarrollador va al explorador de Windows y cambia el modo de solo lectura del archivo
- Edite la configuración para adaptarla a su entorno.
- Verifique en la web.config solo ocurre cuando los valores de implementación cambian o cualquier entrada de configuración se agrega o elimina.
- Esto necesita una buena cantidad de comentarios para cada entrada de configuración, ya que cada desarrollador debe cambiarla
Una forma de lidiar con esto es tener un sistema tokenizado y usar un script de rake para cambiar los valores.
Un método más rudimentario podría ser tener un enlace a un archivo AppSettings.config para todas las AppSettings en su web.config (similar a las conexiones), es decir,
<appSettings configSource="_configs/AppSettings.config" />
Luego, tenga una carpeta con cada uno de sus desarrolladores tenga una versión en una subcarpeta (es decir, / _configs / dave /). Luego, cuando un desarrollador está trabajando en su propio código, copian desde la subcarpeta a la raíz de la carpeta vinculada.
Deberá asegurarse de comunicar los cambios a estos archivos (a menos que lo haga). Si mantiene el archivo AppSettings.config fuera del control de la fuente y solo revisa las carpetas individuales de desarrolladores (todas ellas), entonces se verán forzadas a copiar la correcta.
Prefiero tokenización, pero puede ser más difícil ponerme en funcionamiento si esto solo pretende ser una solución rápida.
Usamos un sistema que combina varias de las respuestas existentes en esta página, además de recurrir a esta sugerencia de Scott Hanselman .
En resumen, lo que hicimos fue tener un app.config / web.config común, y tener la mayoría de las configuraciones específicas en archivos individuales, como lo sugieren otras respuestas aquí. por ejemplo, para nuestra configuración de SMTP, la aplicación contiene
<system.net>
<mailSettings>
<smtp configSource="config/smtp.config" />
</mailSettings>
</system.net>
Este archivo está en control de fuente. Sin embargo, los archivos individuales, como este, no son:
<?xml version="1.0" encoding="utf-8" ?>
<smtp deliveryMethod="Network">
<network host="127.0.0.1" port="25" defaultCredentials="false" password="" userName ="" />
</smtp>
Sin embargo, eso no es exactamente donde termina la historia. ¿Qué hay de los nuevos desarrolladores o una nueva instalación de origen? La mayor parte de la configuración ya no está en control de fuente, y es complicado construir manualmente todos los archivos .config que necesitan. Prefiero tener una fuente que compile al menos de manera inmediata.
Por lo tanto, mantenemos una versión de los archivos .config en el control de código fuente, llamados archivos .config.default . Un árbol fuente nuevo por lo tanto se ve así:
Aún así, no sirve para nada al desarrollador, ya que para Visual Studio no son más que archivos de texto sin sentido. Por lo tanto, el archivo por lotes, copy_default_config.bat
, se encarga de crear un conjunto inicial de archivos .config a partir de los archivos .config.default:
@echo off
@REM Makes copies of all .default files without the .default extension, only if it doesn''t already exist. Does the same recursively through all child folders.
for /r %%f in (*.default) do (
if not exist "%%~pnf" (echo Copying %%~pnf.default to %%~pnf & copy "%%f" "%%~pnf" /y)
)
echo Done.
La secuencia de comandos se puede volver a ejecutar con seguridad, ya que los desarrolladores que ya tienen sus archivos .config no los sobrescribirán. Por lo tanto, uno podría concebiblemente ejecutar este archivo por lotes como un evento previo a la construcción. Los valores en los archivos .default pueden no ser exactamente correctos para una nueva instalación, pero son un punto de partida razonable.
En definitiva, lo que termina con cada desarrollador es una carpeta de archivos de configuración que se ve así:
Puede parecer un poco intrincado, pero definitivamente es preferible a la molestia de los desarrolladores pisando los dedos del otro.