Dans le paragraphe du dessus, on constate qu’on ne peut définir qu’un élément dans notre section. Il pourrait être intéressant dans certains cas d'avoir une section personnalisée qui puisse contenir plusieurs éléments, par exemple pour avoir une liste de personnes.
Pour ce faire, on utilisera
la classe ConfigurationPropertyCollection.
La première chose est de créer un élément en dérivant de
la classe ConfigurationElement. Cet élément va ressembler beaucoup à ce qu’on a fait pour créer une section personnalisée :
Code : C# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | public class ClientElement : ConfigurationElement
{
private static readonly ConfigurationPropertyCollection _proprietes;
private static readonly ConfigurationProperty age;
private static readonly ConfigurationProperty prenom;
static ClientElement()
{
prenom = new ConfigurationProperty("prenom", typeof(string), null, ConfigurationPropertyOptions.IsKey);
age = new ConfigurationProperty("age", typeof(int), null, ConfigurationPropertyOptions.IsRequired);
_proprietes = new ConfigurationPropertyCollection { prenom, age };
}
public string Prenom
{
get { return (string)this["prenom"]; }
set { this["prenom"] = value; }
}
public int Age
{
get { return (int)this["age"]; }
set { this["age"] = value; }
}
protected override ConfigurationPropertyCollection Properties
{
get { return _proprietes; }
}
}
|
Ici, je définis deux propriétés,
Prenom et
Age, qui me permettent bien sûr d’y stocker un prénom et un âge qui sont respectivement une chaine de caractères et un entier. À noter que nous avons besoin de décrire ces propriétés dans le constructeur statique de la classe. Pour cela, il faut lui indiquer son nom, c’est-à-dire la chaine qui sera utilisée comme attribut dans l’élément de la section de configuration. Puis nous lui indiquons son type, pour cela on utilise le mot-clé
typeof qui permet justement de renvoyer le type (dans le sens objet
Type) d’un type. Enfin nous lui indiquons une option, par exemple le prénom sera la clé de mon élément (qui est une valeur unique et obligatoire à saisir) et l’âge, qui sera un élément obligatoire à saisir également.
Ensuite, nous avons besoin d’utiliser cette classe à travers une collection d’éléments. Pour ce faire, il faut créer une classe qui dérive de
ConfigurationElementCollection :
Code : C# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 | public class ClientElementCollection : ConfigurationElementCollection
{
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override string ElementName
{
get { return "Client"; }
}
protected override ConfigurationPropertyCollection Properties
{
get { return new ConfigurationPropertyCollection(); }
}
public ClientElement this[int index]
{
get { return (ClientElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public new ClientElement this[string nom]
{
get { return (ClientElement)BaseGet(nom); }
}
public void Add(ClientElement item)
{
BaseAdd(item);
}
public void Remove(ClientElement item)
{
BaseRemove(item);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new ClientElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ClientElement)element).Prenom;
}
}
|
Ces classes ont toujours la même structure. Ce qui est important de voir est qu’on utilise à l’intérieur la classe
ClientElement pour indiquer le type de la collection. Nous indiquons également le nom de la balise qui sera utilisée dans le fichier de configuration, c’est la chaine « Client » que renvoie la propriété
ElementName. Enfin, j’ai la possibilité de définir ma clé en substituant la méthode
GetElementKey. Le reste des méthodes appellent les méthodes de la classe mère.
Enfin, il faut créer notre section personnalisée, qui dérive comme d’habitude de
ConfigurationSection :
Code : C# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | public class ListeClientSection : ConfigurationSection
{
private static readonly ConfigurationPropertyCollection proprietes;
private static readonly ConfigurationProperty liste;
static ListeClientSection()
{
liste = new ConfigurationProperty(string.Empty, typeof(ClientElementCollection), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsDefaultCollection);
proprietes = new ConfigurationPropertyCollection { liste };
}
public ClientElementCollection Listes
{
get { return (ClientElementCollection)base[liste]; }
}
public new ClientElement this[string nom]
{
get { return Listes[nom]; }
}
protected override ConfigurationPropertyCollection Properties
{
get { return proprietes; }
}
}
|
Notons dans cette classe comment nous utilisons l’opérateur d’indexation pour renvoyer un élément à partir de sa clé et renvoyer la liste des éléments.
Maintenant, nous pouvons écrire notre configuration :
Code : XML | <configuration>
<configSections>
<section name="ListeClientSection" type="MaPremiereApplication.ListeClientSection, MaPremiereApplication" />
</configSections>
<ListeClientSection>
<Client prenom="Nicolas" age="30"/>
<Client prenom="Jérémie" age="20"/>
</ListeClientSection>
</configuration>
|
Nous avons besoin à nouveau de définir la section en indiquant son type. Puis nous pouvons créer notre section et positionner notre liste de clients.
Pour accéder à cette section, nous pouvons charger notre section comme avant avec la méthode
GetSection :
Code : C# | ListeClientSection section = (ListeClientSection)ConfigurationManager.GetSection("ListeClientSection");
|
Puis nous pouvons soit itérer sur les éléments de notre section :
Code : C# | foreach (ClientElement clientElement in section.Listes)
{
Console.WriteLine(clientElement.Prenom + " a " + clientElement.Age + " ans");
}
|
Soit accéder à un élément à partir de sa clé :
Code : C# | ClientElement elementNicolas = section["Nicolas"];
Console.WriteLine(elementNicolas.Prenom + " a " + elementNicolas.Age + " ans");
ClientElement elementJeremie = section["Jérémie"];
Console.WriteLine(elementJeremie.Prenom + " a " + elementJeremie.Age + " ans");
|
Ce qui donnera :
Code : Console | Nicolas a 30 ans
Jérémie a 20 ans |
Voilà pour ce petit tour sur la configuration d’une application. Nous y avons découvert plusieurs façons d’y stocker des paramètres utilisables par notre application. Il faut savoir que beaucoup de composants du framework .NET sont intimement liés à ce fichier de configuration, comme une application web créée avec ASP.NET ou lorsqu’on utilise des services web.
Il est important de remarquer que ce fichier est un fichier de configuration d’application. Il y a d’autres endroits du même genre pour stocker de la configuration pour les applications .NET, comme le
machine.config qui est un fichier de configuration partagé par toutes les applications de la machine. Il y a un héritage entre les différents fichiers de configuration. Si l’on définit une configuration au niveau machine (dans le
machine.config), il est possible de la redéfinir pour notre application (
app.config). En général, le fichier
machine.config se trouve dans le répertoire d’installation du framework .NET, c'est-à-dire dans un sous répertoire du système d’exploitation, dépendant de la version du framework .NET installée. Chez moi par exemple, il se trouve dans le répertoire :
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config.
Enfin, remarquons qu’il est possible de faire des modifications du fichier de configuration directement depuis le code de notre application. C’est un point qui est rarement utilisé et que j’ai choisi de ne pas présenter pour que le chapitre ne soit pas trop long.