Si vous cherchez une section de configuration personnalisée comme la suivante
<CustomApplicationConfig>
<Credentials Username="itsme" Password="mypassword"/>
<PrimaryAgent Address="10.5.64.26" Port="3560"/>
<SecondaryAgent Address="10.5.64.7" Port="3570"/>
<Site Id="123" />
<Lanes>
<Lane Id="1" PointId="north" Direction="Entry"/>
<Lane Id="2" PointId="south" Direction="Exit"/>
</Lanes>
</CustomApplicationConfig>
alors vous pouvez utiliser mon implémentation de la section configuration donc pour commencer ajoutez System.Configuration
référence d'assemblage à votre projet
Regardez les éléments imbriqués que j'ai utilisés, le premier est Credentials avec deux attributs, ajoutons-le en premier.
Élément d'accréditation
public class CredentialsConfigElement : System.Configuration.ConfigurationElement
{
[ConfigurationProperty("Username")]
public string Username
{
get
{
return base["Username"] as string;
}
}
[ConfigurationProperty("Password")]
public string Password
{
get
{
return base["Password"] as string;
}
}
}
PrimaryAgent et SecondaryAgent
Les deux ont les mêmes attributs et semblent être une adresse pour un ensemble de serveurs pour un primaire et un basculement, donc vous avez juste besoin de créer une classe d'élément pour les deux comme suit
public class ServerInfoConfigElement : ConfigurationElement
{
[ConfigurationProperty("Address")]
public string Address
{
get
{
return base["Address"] as string;
}
}
[ConfigurationProperty("Port")]
public int? Port
{
get
{
return base["Port"] as int?;
}
}
}
J'expliquerai comment utiliser deux éléments différents avec une seule classe plus tard dans ce post, sautons le SiteId car il n'y a aucune différence. Il suffit de créer une classe comme 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
public class LaneConfigElement : ConfigurationElement
{
[ConfigurationProperty("Id")]
public string Id
{
get
{
return base["Id"] as string;
}
}
[ConfigurationProperty("PointId")]
public string PointId
{
get
{
return base["PointId"] as string;
}
}
[ConfigurationProperty("Direction")]
public Direction? Direction
{
get
{
return base["Direction"] as Direction?;
}
}
}
public enum Direction
{
Entry,
Exit
}
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'énumération, l'application lancera un message d'erreur. System.Configuration.ConfigurationErrorsException
au démarrage. Ok, passons à la définition de la collection
[ConfigurationCollection(typeof(LaneConfigElement), AddItemName = "Lane", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class LaneConfigCollection : ConfigurationElementCollection
{
public LaneConfigElement this[int index]
{
get { return (LaneConfigElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public void Add(LaneConfigElement serviceConfig)
{
BaseAdd(serviceConfig);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new LaneConfigElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((LaneConfigElement)element).Id;
}
public void Remove(LaneConfigElement serviceConfig)
{
BaseRemove(serviceConfig.Id);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(String name)
{
BaseRemove(name);
}
}
vous pouvez remarquer que j'ai mis le AddItemName = "Lane"
vous pouvez choisir ce que vous voulez pour l'élément d'entrée de votre collection, je préfère utiliser "add", l'élément par défaut, mais je l'ai changé juste pour les besoins de cet article.
Maintenant que tous nos éléments imbriqués ont été implémentés, nous devons les regrouper dans une classe qui doit implémenter System.Configuration.ConfigurationSection
CustomApplicationConfigSection
public class CustomApplicationConfigSection : System.Configuration.ConfigurationSection
{
private static readonly ILog log = LogManager.GetLogger(typeof(CustomApplicationConfigSection));
public const string SECTION_NAME = "CustomApplicationConfig";
[ConfigurationProperty("Credentials")]
public CredentialsConfigElement Credentials
{
get
{
return base["Credentials"] as CredentialsConfigElement;
}
}
[ConfigurationProperty("PrimaryAgent")]
public ServerInfoConfigElement PrimaryAgent
{
get
{
return base["PrimaryAgent"] as ServerInfoConfigElement;
}
}
[ConfigurationProperty("SecondaryAgent")]
public ServerInfoConfigElement SecondaryAgent
{
get
{
return base["SecondaryAgent"] as ServerInfoConfigElement;
}
}
[ConfigurationProperty("Site")]
public SiteConfigElement Site
{
get
{
return base["Site"] as SiteConfigElement;
}
}
[ConfigurationProperty("Lanes")]
public LaneConfigCollection Lanes
{
get { return base["Lanes"] as LaneConfigCollection; }
}
}
Maintenant vous pouvez voir que nous avons deux propriétés avec le nom PrimaryAgent
y SecondaryAgent
Les deux ont le même type, maintenant vous pouvez facilement comprendre pourquoi nous n'avions qu'une seule classe d'implémentation pour ces deux éléments.
Avant de pouvoir utiliser cette section de configuration nouvellement inventée dans votre app.config (ou web.config), vous devez simplement indiquer à votre application que vous avez inventé votre propre section de configuration et lui accorder un certain respect. Pour ce faire, vous devez ajouter les lignes suivantes dans app.config (peut-être juste après le début de la balise Root).
<configSections>
<section name="CustomApplicationConfig" type="MyNameSpace.CustomApplicationConfigSection, MyAssemblyName" />
</configSections>
NOTE : MyAssemblyName doit être sans .dll. Par exemple, si le nom de votre 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
CustomApplicationConfigSection config = System.Configuration.ConfigurationManager.GetSection(CustomApplicationConfigSection.SECTION_NAME) as CustomApplicationConfigSection;
J'espère que cet article vous aidera à démarrer avec des sections de configuration personnalisées un peu compliquées.
Bon codage :)
****Edit**** Pour activer LINQ on LaneConfigCollection
vous devez mettre en œuvre IEnumerable<LaneConfigElement>
Et ajouter l'implémentation suivante de GetEnumerator
public new IEnumerator<LaneConfigElement> GetEnumerator()
{
int count = base.Count;
for (int i = 0; i < count; i++)
{
yield return base.BaseGet(i) as LaneConfigElement;
}
}
pour les personnes qui ne savent toujours pas comment le rendement fonctionne vraiment, lisez ce bel article
Voici deux points essentiels tirés de l'article ci-dessus
il ne termine pas vraiment l'exécution de la méthode. yield return met en pause l'exécution de la l'exécution de la méthode et la prochaine fois que vous l'appelez (pour la prochaine valeur d'énumération), la méthode continuera à s'exécuter à partir du dernier appel de yield return. C'est un peu confus je pense (Shay Friedman)
Yield n'est pas une fonctionnalité du runtime .Net. Il s'agit simplement d'une fonctionnalité du langage C# qui est compilé en code IL simple par le compilateur C#. (Lars Corneliussen)
0 votes
Je n'arrive pas à le faire fonctionner. J'aimerais voir RT.Core.Config.ServicesSection. Je n'obtiens que l'élément 'AddService' non reconnu, même si j'utilise également le code de la réponse acceptée.
0 votes
J'ai manqué ça aussi au début - cette partie : [ConfigurationCollection(typeof(ServiceCollection), AddItemName = "add", ClearItemsName = "clear", RemoveItemName = "remove")] Le AddItemName doit correspondre, donc si vous changez "add" en "addService", cela fonctionnera.