Comment Lire une Section de Configuration à partir de XML dans une Base de données?
J'ai une Config de la classe comme ceci:
public class MyConfig : ConfigurationSection
{
[ConfigurationProperty("MyProperty", IsRequired = true)]
public string MyProperty
{
get { return (string)this["MyProperty"]; }
set { this["MyProperty"] = value; }
}
}
Et elle est instanciée par une autre classe, comme ce
(MyConfig)ConfigurationManager.GetSection("myConfig")
Nous apportons quelques modifications et sont maintenant stocker le fichier de configuration dans la base de données en xml, exactement comme il est actuellement dans le fichier de configuration.
Je tiens à maintenir la Maconfig comme un ConfigurationSection pour la compatibilité ascendante, mais encore être en mesure d'instancier à l'aide de la chaîne XML récupéré à partir de la DB.
Est-il possible? Si oui, comment? (Gardez à l'esprit qu'il doit encore travailler comme instancié ci-dessus)
- Je voudrais amour pour voir une solution à ce - que j'ai fait des recherches pendant un certain temps, sans grand succès, malheureusement....
- Je suis content de voir que je ne suis pas le seul.
- Je ne sais pas la réponse à celui-ci car il semble que l'emplacement des fichiers de configuration ne peut pas être changé par le code de l'application. Mais je ne voudrais pas surcharger les fichiers de configuration pour ce scénario permettrait de créer ma propre configuration lecteur qui permettrait d'obtenir les données de la DB.
- J'ai été envisagent sérieusement de faire ce que vous avez suggéré. J'ai pensé que j'ai demandé avant d'aller dans cette direction
- eh bien, le principal problème est que je ne pouvais pas vraiment trouver un moyen de brancher ma propre base de données à base de config reader. L'ensemble de l' .NET configuration du système n'est malheureusement pas en fonction de fournisseur (comme beaucoup d'autres choses .NET), et de nombreuses classes sont scellés et à l'utilisation interne et les méthodes privées 🙁
Vous devez vous connecter pour publier un commentaire.
Ma suggestion serait de conserver votre Maconfig classe, mais la charge de votre XML à partir de votre base de données dans le constructeur, puis dans chacune des propriétés de votre Maconfig, vous pouvez mettre dans la logique pour déterminer où vous obtenez la valeur à partir de (base de données ou .fichier de config) si vous avez besoin de pull config à partir d'un emplacement, ou le faire tomber si la valeur est vide.
Voici comment j'ai l'habitude de le faire: il suffit d'ajouter ces membres de la Maconfig classe:
De cette façon, vous n'avez rien à changer dans la Maconfig classe, mais vous avez encore besoin de modifier la façon dont vos clients ont accès, avec ce genre de code:
Si vous avez besoin d'obtenir toute Système.La Configuration.ConfigurationSection stockées dans la base de données, vous pouvez envisager d'écrire des génériques de la section lecteur comme ceci:
Cela fonctionne pour toutes les classes qui remplacent DeserializeElement méthode. par exemple,
Que vous pourriez obtenir une section comme celle-ci:
C'est un problème difficile. Vous pourriez avoir un fichier de config avec quelques délibérément XML incorrecte, remplacer OnDeserializeUnrecognizedElement dans votre ConfigurationSection et puis contourner efficacement le fichier à ConfigurationSection cartographie (essentiellement l'ensemble de vos propriétés manuellement) - remaniement serait nécessaire, mais vous pouvez toujours exposer les mêmes propriétés, etc. C'est un peu WTF, mais peut-être réalisable.
Je décrivent essentiellement comment faire cela avec LINQ to XML dans ce post de blog. Dans l'ensemble de mon code maintenant, je n'ai pas de classes qui s'appuient sur ConfigurationSection, j'utilise la technique décrite dans mon post du blog de dérivation et de retour POCOs à travers une interface. Cela a fait mon code unité vérifiable, que je peux facilement utiliser un stub pour l'interface.
Je peux aussi me déplacer facilement ma configuration dans un DB-je souhaiter de le faire - je viens de créer une nouvelle classe qui implémente mon interface de configuration et de passer dans mon Cio de configuration. Microsoft n'a pas conçu le système de configuration pour être flexible, de sorte que vous devez prendre cela en considération lorsque vous l'utilisez dans votre propre code.
La seule autre façon que je peux penser est d'écrire la DB config dans un fichier, puis de le lire, mais qui est aussi bizarre!
Plutôt vieille question, mais tout simplement jouer avec une solution à cette question. Il est similaire à Simon Mourier de l'approche (que j'aime mieux, à certains égards, moins hacky), mais ne signifie pas tout le code qui appelle
System.Configuration.ConfigurationManager.GetSection()
va continuer à travailler sans avoir à les modifier pour utiliser la méthode statique, donc peut conduire à moins d'un changement de code dans l'ensemble.La base de la première mise en garde est que je n'ai aucune idée si cela fonctionne avec les sections imbriquées, mais je suis presque certain qu'il ne sera pas. La quasi-principal inconvénient est qu'il nécessite des modifications à la section de configuration de la classe, de sorte que vous pouvez l'utiliser seulement avec des rubriques personnalisées que vous avez la source (et sont autorisés à changer!)
La deuxième et OPPOSITION PRINCIPALE, c'est que je suis en train de jouer avec cela, je ne suis pas à l'utiliser dans le développement et certainement pas la production, et tout simplement de traînées de mon propre code sur les fonctionnalités de base, comme cela peut avoir un effet d'entraînement qui ne se présentent pas dans mon exemple. Utiliser à vos propres risques.
(Cela dit, je me suis mise à l'essai dans un Umbraco site, donc avec des charges d'autres sections de configuration en cours, et ils ont encore tout le travail, donc je pense qu'il n'a pas immédiatement des effets terribles)
EDIT: C'est .NET 4, pas 3.5 comme pour la question d'origine. Aucune idée si c'wil faire une différence.
Donc, voici le code assez simple, il suffit de remplacer
DeserializeSection
d'utiliser un lecteur XML qui se charge à partir d'une base de données.Je suis en utilisant ASP.Net, afin de le faire fonctionner, vous avez besoin d'un
web.config
, mais alors hey, j'ai besoin d'un endroit pour les chaînes de connexion de toute façon, ou je ne vais pas vous connecter à une base de données à tous.Personnalisé de votre article doit être défini comme normal dans
<configSections/>
; la clé pour faire ce travail est de mettre ensuite un élément vide à la place de vos réglages normaux; c'est à dire à la place de<TestSettings configSource="..."/>
ou vous inline paramètres, il suffit de mettre<TestSettings/>
Le gestionnaire de configuration puis de charger toutes les sections, voir l'existant
<TestSettings/>
élément, et désérialiser, à quel point il frappe votre remplacement et charge le XML à partir de la base de données au lieu.NOTE: Le désérialiser s'attend à un fragment de document (il s'attend à être appelé lorsque le lecteur est déjà situé sur un nœud), et non pas l'ensemble d'un document, donc, si vos articles sont stockés dans des fichiers séparés, vous devez supprimer le
<?xml ?>
déclaration de la première, ou que vous obtenezExpected to find an element
.