2009-07-21 5 views
2

J'ai une application client-serveur, où il existe deux options pour le serveur - exécutable autonome ou dans un autre AppDomain dans le client, ce qui est très pratique pour le débogage. Le choix du serveur est transparent pour le client, le seul fichier qui doit être changé est le client app.config. Pour passer du serveur autonome au serveur local, certaines sections doivent être non commentées (comme la configuration de nhibernate, qui ne concerne que le serveur) avec des paramètres individuels (comme l'implémentation de l'authentification, qui est de nouveau seulement pertinent pour le serveur). À partir de maintenant, la commutation entre les deux modes est fastidieuse et sujette aux erreurs, car il faut (dé) commenter plusieurs sections et paramètres individuels.Paramètres de l'application .NET conditionnelle

Existe-t-il un moyen de spécifier des paramètres/sections conditionnels dans app.config? Ou peut-être existe-t-il un moyen d'inclure un autre fichier de configuration dans le fichier app.config? De cette façon, nous pourrions mettre tous les paramètres spécifiques au serveur local dans un autre fichier et seulement (dé) commenter son inclusion.

Je voudrais souligner le fait que je souhaite avoir des sections conditionnelles, en plus des paramètres d'application.

Note finale. Le scénario décrit n'est évidemment pas pour la production. Il est utilisé exclusivement pour exécuter des tests unitaires. Nous utilisons mstest pour nos tests unitaires.

Merci.

Répondre

2

Pour votre appsettings normal, la norme serait d'utiliser ceci:

<appSettings file="appSettings.config" /> 

Pour d'autres sections que vous pouvez utiliser

<mySection configSource="mySection.config" /> 

Vous devez avoir un fichier par section, et la configSource ne fera que travailler avec des chemins relatifs.

Pour votre cas particulier, je recommanderais un dossier pour chaque installation/configuration.

<mySection1 configSource="setup1\mySection1.config" /> 
<mySection2 configSource="setup1\mySection2.config" /> 

Ensuite, vous pouvez le faire manuellement un texte « rechercher et remplacer » sur le nom du dossier pour basculer entre les configurations, ou exécuter un fichier batch ou construire étape qui fait passer le dossier sur le système de fichiers (par exemple copier le dossier Setup1 à un dossier currentSetup)

Notez que vous ne pouvez pas utiliser un configSource sur system.serviceModel, mais vous pouvez pour ses sous-sections

+1

Que se passe-t-il si configSource fait référence à un fichier non existant? La section est-elle silencieusement ignorée ou l'application ne parvient-elle pas à se configurer elle-même? – mark

+0

Vous devez obtenir une erreur de configuration de l'application, même si l'élément de configuration est facultatif – MattH

1

Une approche consiste à utiliser des événements de construction. Créez deux fichiers de paramètres d'application, chacun nommé en fonction du type de déploiement. Créez une nouvelle configuration de construction pour chaque type de déploiement. Avoir un événement de préconfiguration qui détermine le type de configuration de construction en cours d'exécution, puis créer le fichier "app.config" en copiant le fichier de configuration spécialisé et en le nommant "app.config".

+0

N'oubliez pas de le copier dans le outputdir ou il y aura des problèmes avec les systèmes de contrôle de source. – Mo0gles

4

Dans ASP.NET, il est possible d'avoir des paramètres dans un fichier externe (mais je ne suis pas sûr si cela est également disponible dans les applications Windows):

Mise à jour: cela fonctionne aussi pour la console/Winforms applications.

web.config/app.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <!-- comment one of the following two lines --> 

    <!--appSettings--> 
    <appSettings file="YourSettings.config"> 

    <add key="KeyToOverride" value="Original" /> 
    <add key="KeyToNotOverride" value="Standard" /> 

    </appSettings> 
</configuration> 

YourSettings.config:

<appSettings> 
    <add key="KeyToOverride" value="Overridden" /> 
    <add key="KeyToBeAdded" value="EntirelyNew" /> 
</appSettings> 
+0

Oui, mais qu'en est-il des sections? NHibernate, log4net, d'autres bibliothèques définissent leurs propres sections de configuration. Peuvent-ils être déplacés vers un autre fichier de configuration? Selon MSDN - pas. – mark

0

nAnt peut-être une autre solution.

+0

nAnt, si je ne me trompe pas, est un outil de construction. Comme msbuild, maven ou make. Comment l'utiliser peut m'aider à gérer les paramètres de configuration de l'application? – mark

+0

C'est un outil de script qui peut faire des builds, exécuter des tests et gérer les paramètres de configuration de l'application. Là où je travaille, nous l'utilisons pour générer des fichiers app.config et web.config dans nos projets. Je suppose en quelque sorte qu'un tel outil pourrait être utilisé pour automatiser les changements des fichiers de configuration à travers une interface de ligne de commande qui est une approche acceptable pour résoudre le problème. –

+0

Nous utilisons msbuild. Nous l'utilisons pour construire, exécuter une analyse de code statique (en utilisant fxcop) et invoquer nos tests unitaires ainsi que d'autres choses. Autant que je sache, il est aussi capable que Nant. Je suppose qu'il peut être utilisé pour créer un fichier app.config à partir d'un modèle basé sur un paramètre de ligne de commande. C'est le dernier recours, si rien d'autre ne fonctionne. – mark

1

Ajouter un nouveau paramètre - AppType = Server/Standalone - dupliquer chaque paramètre dans App.Config qui change en fonction de Server/Standalone pour qu'il y ait seulement 1 app.config indépendamment de Server/Standalone. Déplacez les choix conditionnels dans votre application.

if(AppType == ApplicationType.Server) 
{ 
    Setup(NHibernate); 
    Setup(Authentication Implementation); 
} 
else 
{ 
    Setup(Standalone app stuff); 
} 
+1

Exactement. Créez des sections distinctes dans le fichier App.Config et contrôlez lequel est chargé par un commutateur de ligne de commande à l'application. –

+0

Ne semble pas que nous pouvons utiliser cette approche. Certains paramètres sont destinés aux bibliothèques tierces (comme CSLA, log4net, etc ...), qui les lisent à leur convenance. Il n'est pas clair comment étendre l'exemple NHibernate à un cas général. – mark

1

Le fichier app.config ou web.config peut faire référence à un fichier de configuration externe.

<configuration> 
    <appSettings file="external.config"> 
    </appSettings> 
</configuration> 

MSDN appSettings reference

+0

Oui, mais qu'en est-il des sections? NHibernate, log4net, d'autres bibliothèques définissent leurs propres sections de configuration.Peuvent-ils être déplacés vers un autre fichier de configuration? Selon MSDN - pas. – mark

1

système.Les supports de configuration incluent les fichiers avec l'attribut configsource. Voir ici http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource.aspx ou ici http://rizwanshah.blogspot.com/2007/10/use-configsource-attribute-to-manage.html

Vous pouvez l'utiliser comme ceci:

<SomeSection configSource="myOtherFile.config" /> 

Nous avons utilisé pour ajouter des sections différentes à la configuration déclarative WCF etc/

+1

S'il y a deux sections différentes, alors il devrait y avoir deux fichiers configSource différents? Ou un fichier peut contenir différentes sections et être le configSource pour plusieurs sections distinctes? – mark

+0

pas sûr - nous l'avons fait en ayant différentes sections dans différents fichiers seulement. Non vérifié dans l'autre sens –

+1

Malheureusement, vous devez utiliser un fichier par type de section. Voir ma réponse pour une alternative qui devrait être presque aussi facile pour vous de travailler avec. – MattH

0

Réponse simple: Il suffit d'utiliser une ligne de commande argument. Je travaille actuellement sur un projet qui doit passer de 'local' (à des fins de test/débogage) à 'server' (quand je le déploie sur une machine de production). J'ai juste visual studio passer 'local' comme un argument de ligne de commande quand je suis en mode de débogage, et utiliser la présence de cet argument pour configurer le logiciel à l'exécution pour faire ce que j'ai besoin de faire.

L'absence de tout argument fait que le logiciel se comporte comme s'il était en production. Lorsque le logiciel est prêt pour la publication, je supprime complètement la logique d'argument.