Si vous recherchez une section de configuration personnalisée comme suit
<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 de configuration afin de commencer, ajoutez une System.Configuration
référence d'assemblage à votre projet
Regardez 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
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 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
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 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
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'application d'énumération lèvera un System.Configuration.ConfigurationErrorsException
au démarrage. Ok passons à la définition de 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 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
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; }
}
}
Vous pouvez maintenant voir que nous avons deux propriétés avec un nom PrimaryAgent
et que les SecondaryAgent
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).
<configSections>
<section name="CustomApplicationConfig" type="MyNameSpace.CustomApplicationConfigSection, MyAssemblyName" />
</configSections>
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
CustomApplicationConfigSection config = System.Configuration.ConfigurationManager.GetSection(CustomApplicationConfigSection.SECTION_NAME) as CustomApplicationConfigSection;
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
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 fonctionne vraiment le rendement, lisez ce bel article
Deux points clés tirés de l'article ci-dessus sont
cela ne met pas vraiment fin à l'exécution de la méthode. yield return interrompt l'exécution de la méthode et la prochaine fois que vous l'appelez (pour la valeur d'énumération suivante), la méthode continuera à s'exécuter à partir du dernier appel de yield return. Cela semble un peu déroutant je pense ... (Shay Friedman)
Le rendement n'est pas une fonctionnalité du runtime .Net. Il s'agit simplement d'une fonctionnalité de langage C # qui est compilée en code IL simple par le compilateur C #. (Lars Corneliussen)