2009-05-08 9 views
11

J'ai finalement réussi à construire une solution de travail d'une architecture de plugin avec l'aide de certains gars ici, mais maintenant un nouveau problème se pose.Plugin pour utiliser son propre app.config

Mon application d'hébergement utilise son fichier app.config pour certaines valeurs par défaut de l'assembly d'exécution (qui est un service Windows).

Chaque plugin devrait être capable de charger ses propres paramètres à partir d'un fichier de paramètres de plugin séparé car l'hôte ne devrait pas être informé des paramètres du plugin. Dans le projet de plugin j'ai ajouté un fichier app.config ainsi (avec quelques paramètres et une chaîne de connexion) pour que je puisse instancier la classe Properties.Settings et utiliser ses propriétés dans le code du plugin. Le problème est quand je change les paramètres dans le app.config du plugin (qui est construit comme plugin.dll.config) Je ne peux pas voir ces changements dans le plugin lui-même, qui utilise toujours les paramètres de conception .

Existe-t-il un moyen de charger les paramètres app.config dans chaque plugin pour que la classe Properties.Settings générée fonctionne? Sinon, existe-t-il un autre moyen de charger un fichier de paramètres basé sur app.config dans le plugin? Je prévois d'ajouter une méthode LoadConfiguration dans l'interface IPlugin afin que chaque plugin charge ses propres paramètres.

Répondre

2

Est-ce que quelque chose comme ConfigurationManager.OpenMappedExeConfiguration aiderait ici? Vous pouvez créer un objet Configuration lisant dans les valeurs d'un fichier spécifique.

+0

J'ai effectivement essayé cela, mais d'une manière ou d'une autre cela ne semble pas fonctionner. –

+0

Un autre problème qui empêche cela de fonctionner est que vous aurez une instance de configuration mais la classe Properties.Settings générée ne fonctionnera pas. –

3

Vous travaillez avec l'architecture de app.config. Vous obtenez un fichier app.config par fichier exécutable (EXE, pas DLL). L'exécutable se lance, crée son AppDomain et charge MyApp.exe.config. Vous pouvez ajouter des objets app.config dans Visual Studio, mais ils sont ignorés pour les DLL. Je pense que ce que vous voulez faire est de copier manuellement le XML à partir du fichier dll.config et de le coller dans le niveau de l'application app.config. (Je suis sûr qu'il existe un moyen d'automatiser cela en utilisant TeamBuild ou un tel.) Les valeurs substituées seront alors disponibles pour votre classe Properties.Settings.

+0

Oui, mais la question indique clairement que l'application ne doit pas être au courant des paramètres du plugin. – ChrisF

+0

Cela dit, je serais satisfait si je pouvais injecter de façon dynamique les paramètres du plugin dans le fichier de configuration app.config principal à l'exécution. Le problème ici est que j'ai aussi besoin du chapitre settingtring setting des fichiers app.config de mes plugins car ils fonctionnent presque tous dans des bases de données SQL Server. –

+0

Si chaque plug-in a été créé dans son propre AppDomain (généralement une bonne idée, il apparaîtra à partir d'autres publications sur SO), alors vous pourriez être en mesure de le convaincre de charger un fichier de configuration différent pour le nouvel AppContext. –

2

Je préfère construire et utiliser un plugin de type IConfigManager. Ce travail consiste à expliquer comment la configuration est stockée. Vous recevez une instance de celui-ci via l'injection de dépendance. De cette façon, l'implémentation IConfigManager peut charger des paramètres à partir de plusieurs fichiers .config, à partir du réseau, d'une base de données ou de toute autre source. Je l'utilise également pour fournir des valeurs par défaut basées sur l'utilisateur, la machine et/ou l'application - qui peuvent être remplacées par l'utilisateur, par ex.

D'autres avantages de cette méthode sont que les paramètres peuvent être conservés de manière cohérente dans tous les plugins - sans les plugins, l'endroit où votre plugin stocke ses paramètres peut changer de manière transparente (de. config to other) et enfin, IConfigManager peut être raillé pendant les tests unitaires pour simuler différentes situations.

J'espère que cela aide.

+0

Je suis intrigué par cette approche. Pourriez-vous poster un exemple ou un lien vers un exemple? – HitLikeAHammer

+0

Salut Rick, Je ne suis pas sûr que je pourrais serrer beaucoup d'un exemple dans ce commentaire. Je n'ai pas de lien vers quelque chose de spécifique à cette réponse - je pourrais écrire un billet de blog si j'avais un blog. Y at-il une partie de ce que j'ai dit que vous aimeriez en savoir plus? Je vais voir si je peux créer un blog quelque part et écrire à ce sujet, mais ce ne sera pas rapide. Cheers. –

1

Je suis un collègue d'Erik. Comme il passera des vacances bien méritées dans les prochaines semaines, je vais développer un peu plus sur ce sujet.

Dans nos plugins, nous utilisons plusieurs instances de clients du service WCF. La chose intéressante de ces services est qu'ils viennent avec des sections app.config que vous pouvez utiliser pour configurer le comportement, le type de service, la sécurité, etc.

Maintenant, quand nous chargeons nos plugins, ces sections sont manquantes dans config et par conséquent, les points de terminaison corrects ne peuvent pas être trouvés. Bien sûr, nous pourrions les mettre dans le code, mais ce genre de choses ébranle la possibilité de définir d'autres options de configuration le long du chemin en cas de besoin. Nous pourrions vouloir implémenter ws-security par exemple.

Nous avons donc besoin d'un moyen de charger ces configurations afin que les plugins puissent y lire leurs paramètres respectifs. Nous pourrions bien sûr fusionner toutes les configs en une seule, mais cela élimine la méthode "juste plugin" puisque vous devriez gérer les configs à côté de l'installation du plugin.

Je pensais à la création d'un petit outil qui fusionnerait la configuration 'master' avec toutes les configurations placées dans un sous-répertoire du projet et remplacerait le fichier .exe.config par celui-là. Je pense que cela fonctionnerait, mais je me demandais si .NET ne fournit pas de meilleures options. Les AppDomains multiples ne fonctionnent pas car les plugins doivent interagir entre eux (modèle fournisseur/consommateur) et nous ne souhaitons pas passer à l'accès distant à cause de ce problème. Mise à jour: J'ai corrigé la plupart des problèmes en utilisant le ConfigurationManager pour ouvrir les configurations existantes pour lire appSettings. Comme pour les clients WCF; Vous pouvez charger la configuration du point de terminaison/liaison pour le serveur et le client comme indiqué ici: http://weblogs.asp.net/cibrax/archive/2007/10/19/loading-the-wcf-configuration-from-different-files-on-the-client-side.aspx

+0

Savez-vous qu'il est possible de référencer un fichier .config externe à partir du fichier app.config/web.config principal? De cette façon, vous pouvez conserver vos paramètres de plugin dans un fichier séparé et ajouter simplement une référence à la configuration principale. De toute façon, vous devez enregistrer les plugins, donc je ne vois pas cela comme une grosse affaire. – Aaronaught

1

Vous pouvez faire en sorte que chaque plug-in lise sa propre ConfigurationSection puis, dans le fichier de configuration principal, utilisez le paramètre ConfigSource pour pointer vers un fichier externe. (Voir ce link pour plus d'informations)

Vous n'échapperez pas complètement aux informations de configuration du plugin dans le fichier app.config principal mais au moins les paramètres spécifiques du plugin sont dans des fichiers séparés.

0

Je préfère généralement éviter tout le désordre app.config en créant un fichier Xml dédié que l'hôte traite avec les paramètres du plugin à l'intérieur. Le Xml ressemblerait à quelque chose comme ceci:

<root> 
    <Settings> 
     Here's where anything specific to the app goes. 
    </Settings> 
    <plugins> 
     <plugin type="mylibrary.myclass"> 
      Here I let the plugin serialize itself however it wants to. 
     </plugin> 
    </plugins> 
</root> 

L'application d'hébergement crée alors le plug-in à partir du type attribut et teste si la classe implémente ISerializable; si c'est le cas, le plugin se désérialisera. C'est un peu effrayant d'avoir les plugins en ligne avec les paramètres de l'application, mais si vous chargez la sous-chaîne de Xml dans un nouveau XmlReader alors vous n'avez pas à vous soucier d'une erreur dans le plugin de lire trop loin dans le Xml chaîne.

Questions connexes