J'essaie d'implémenter une section de configuration personnalisée dans un projet et je continue à me heurter à des exceptions que je ne comprends pas. J'espère que quelqu'un pourra remplir les blancs ici.
J'ai App.config
qui ressemble à ceci:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ServicesSection" type="RT.Core.Config.ServicesConfigurationSectionHandler, RT.Core"/>
</configSections>
<ServicesSection type="RT.Core.Config.ServicesSection, RT.Core">
<Services>
<AddService Port="6996" ReportType="File" />
<AddService Port="7001" ReportType="Other" />
</Services>
</ServicesSection>
</configuration>
J'ai un ServiceConfig
élément défini comme ceci:
public class ServiceConfig : ConfigurationElement
{
public ServiceConfig() {}
public ServiceConfig(int port, string reportType)
{
Port = port;
ReportType = reportType;
}
[ConfigurationProperty("Port", DefaultValue = 0, IsRequired = true, IsKey = true)]
public int Port
{
get { return (int) this["Port"]; }
set { this["Port"] = value; }
}
[ConfigurationProperty("ReportType", DefaultValue = "File", IsRequired = true, IsKey = false)]
public string ReportType
{
get { return (string) this["ReportType"]; }
set { this["ReportType"] = value; }
}
}
Et j'ai un ServiceCollection
défini comme ceci:
public class ServiceCollection : ConfigurationElementCollection
{
public ServiceCollection()
{
Console.WriteLine("ServiceCollection Constructor");
}
public ServiceConfig this[int index]
{
get { return (ServiceConfig)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public void Add(ServiceConfig serviceConfig)
{
BaseAdd(serviceConfig);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new ServiceConfig();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServiceConfig) element).Port;
}
public void Remove(ServiceConfig serviceConfig)
{
BaseRemove(serviceConfig.Port);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(string name)
{
BaseRemove(name);
}
}
La partie qui me manque est ce qu'il faut faire pour le gestionnaire. À l'origine, j'ai essayé d'implémenter un IConfigurationSectionHandler
mais j'ai trouvé deux choses:
- ça n'a pas marché
- c'est obsolète.
Je ne sais plus trop quoi faire pour pouvoir lire mes données depuis la configuration. Toute aide s'il vous plaît!
c#
configuration
app-config
configuration-files
Chris Holmes
la source
la source
Réponses:
La réponse précédente est correcte, mais je vous donnerai également tout le code.
Votre app.config devrait ressembler à ceci:
Vos classes
ServiceConfig
et vosServiceCollection
classes restent inchangées.Vous avez besoin d'une nouvelle classe:
Et cela devrait faire l'affaire. Pour le consommer, vous pouvez utiliser:
la source
[Add|Remove|Clear]ItemName
propriétés de l'ConfigurationCollection
attribut ne sont pas vraiment nécessaires dans ce cas, car "ajouter" / "effacer" / "supprimer" sont déjà les noms par défaut des éléments XML.Si vous recherchez une section de configuration personnalisée comme suit
alors vous pouvez utiliser mon implémentation de la section de configuration afin de commencer, ajoutez une
System.Configuration
référence d'assemblage à votre projetRegardez les éléments imbriqués que j'ai utilisés, le premier est les informations d'identification avec deux attributs, alors ajoutons-le d'abord
Élément Credentials
PrimaryAgent et SecondaryAgent
Les deux ont les mêmes attributs et ressemblent à une adresse à un ensemble de serveurs pour un serveur principal et un basculement, il vous suffit donc de créer une classe d'élément pour les deux comme suit
J'expliquerai comment utiliser deux éléments différents avec une classe plus tard dans cet article, laissez-nous sauter le SiteId car il n'y a aucune différence. Il vous suffit de créer une classe identique à celle ci-dessus avec une seule propriété. voyons comment implémenter la collection Lanes
il est divisé en deux parties, vous devez d'abord créer une classe d'implémentation d'élément, puis vous devez créer une classe d'élément de collection
LaneConfigElement
vous pouvez remarquer qu'un attribut de
LanElement
est une énumération et si vous essayez d'utiliser une autre valeur dans la configuration qui n'est pas définie dans l'application d'énumération lèvera unSystem.Configuration.ConfigurationErrorsException
au démarrage. Ok passons à la définition de collectionvous pouvez remarquer que j'ai défini le
AddItemName = "Lane"
vous pouvez choisir ce que vous voulez pour votre élément d'entrée de collection, je préfère utiliser "ajouter" celui par défaut mais je l'ai changé juste pour le bien de ce message.Maintenant, tous nos éléments imbriqués ont été implémentés maintenant, nous devons regrouper tous ceux dans une classe qui doit implémenter
System.Configuration.ConfigurationSection
CustomApplicationConfigSection
Vous pouvez maintenant voir que nous avons deux propriétés avec un nom
PrimaryAgent
et que lesSecondaryAgent
deux ont le même type. Vous pouvez maintenant facilement comprendre pourquoi nous n'avions qu'une seule classe d'implémentation par rapport à ces deux éléments.Avant de pouvoir utiliser cette section de configuration nouvellement inventée dans votre app.config (ou web.config), il vous suffit de dire à votre application que vous avez inventé votre propre section de configuration et de lui donner du respect, pour ce faire, vous devez ajouter les lignes suivantes dans app.config (peut-être juste après le début de la balise racine).
REMARQUE: MyAssemblyName doit être sans .dll, par exemple, si votre nom de fichier d'assemblage est myDll.dll, utilisez myDll au lieu de myDll.dll
pour récupérer cette configuration, utilisez la ligne de code suivante n'importe où dans votre application
J'espère que l'article ci-dessus vous aidera à démarrer avec des sections de configuration personnalisées un peu compliquées.
Bon codage :)
**** Edit **** Pour activer LINQ sur
LaneConfigCollection
vous devez implémenterIEnumerable<LaneConfigElement>
Et ajouter la mise en œuvre suivante de
GetEnumerator
pour les personnes qui ne savent toujours pas comment fonctionne vraiment le rendement, lisez ce bel article
Deux points clés tirés de l'article ci-dessus sont
la source
Ceci est un code générique pour la collecte de configuration:
Une fois que vous l'avez
GenericConfigurationElementCollection
, vous pouvez simplement l'utiliser dans la section config (c'est un exemple de mon Dispatcher):L'élément de configuration est configuré ici:
Le fichier de configuration ressemblerait à ceci:
J'espère que cela vous aidera!
la source
Une alternative plus simple pour ceux qui préféreraient ne pas écrire manuellement toute cette configuration passe-partout ...
1) Installez Nerdle.AutoConfig depuis NuGet
2) Définissez votre type ServiceConfig (soit une classe concrète ou juste une interface, l'un ou l'autre fera l'affaire)
3) Vous aurez besoin d'un type pour contenir la collection, par exemple
4) Ajoutez la section de configuration comme ceci (notez la dénomination camelCase)
5) Carte avec AutoConfig
la source
Essayez d'hériter de ConfigurationSection . Ce billet de blog de Phil Haack a un exemple.
Confirmé, selon la documentation pour IConfigurationSectionHandler :
la source