Procédure pas à pas : création d'un composant à l'aide de Visual C#
Les composants fournissent du code réutilisable sous la forme d'objets. Une application qui utilise le code d'un composant, en créant des objets et en appelant leurs propriétés et méthodes, est appelée un client. Un client peut se trouver ou non dans le même assembly que le composant qu'il utilise.
Comme les procédures suivantes reposent les unes sur les autres, l'ordre dans lequel vous les effectuez est important.
Notes
Les boîtes de dialogue et les commandes de menu qui s'affichent peuvent être différentes de celles qui sont décrites dans l'aide, en fonction de vos paramètres actifs ou de l'édition utilisée. Pour modifier vos paramètres, choisissez Importation et exportation de paramètres dans le menu Outils. Pour plus d'informations, consultez Utilisation des paramètres.
Création du projet
Pour créer la bibliothèque de classes CDemoLib et le composant CDemo
Dans le menu Fichier, sélectionnez Nouveau, puis Projet pour ouvrir la boîte de dialogue Nouveau projet. Sélectionnez le modèle de projet Bibliothèque de classes dans la liste des types de projets Visual C# et entrez CDemoLib dans la zone Nom.
Notes
Indiquez toujours le nom du nouveau projet lorsque vous le créez. Ce faisant, vous définissez l'espace de noms racine, le nom de l'assembly ainsi que celui du projet et vous avez la garantie que le composant par défaut sera placé dans l'espace de noms adéquat.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur CDemoLib et sélectionnez Propriétés dans le menu contextuel. Notez que la zone Espace de noms par défaut contient CDemoLib.
L'espace de noms racine sert à qualifier le nom des composants de l'assembly. Par exemple, si deux assemblys contiennent des composants nommés CDemo, vous pouvez spécifier votre composant CDemo à l'aide de CDemoLib.CDemo.
Fermez la boîte de dialogue.
Dans le menu Projet, choisissez Ajouter un composant.
Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Classe Component, puis dans la zone Nom tapez CDemo.cs. Cliquez sur Ajouter pour créer le composant.
Un composant nommé CDemo est ajouté à la bibliothèque de classes.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur CDemo.cs, puis sélectionnez Afficher le code dans le menu contextuel. L'éditeur de code s'ouvre.
Notez la présence de : Component juste après public partial class CDemo. Cette partie de l'instruction désigne la classe dont votre classe hérite. Par défaut, un composant hérite de la classe Component fournie par le système. La classe Component fournit de nombreuses fonctionnalités pour votre composant et notamment la possibilité d'utiliser des concepteurs.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur Class1.cs, puis sélectionnez Supprimer. Vous supprimez ainsi la classe par défaut fournie par la bibliothèque de classes, laquelle n'est pas utilisée dans cette procédure pas à pas.
Dans le menu Fichier, choisissez Enregistrer tout pour enregistrer le projet.
Ajout de constructeurs et de destructeurs
Les constructeurs déterminent la manière dont votre composant est initialisé et la méthode Finalize celle dont il est détruit. Le code du constructeur et la méthode Finalize de la classe CDemo tiennent à jour en permanence un compteur du nombre d'objets CDemo existants.
Pour ajouter du code pour le constructeur et le destructeur de la classe CDemo
Dans l'éditeur de code, ajoutez des variables membres pour conserver en permanence un total des instances de la classe CDemo et un numéro d'ID pour chaque instance.
public readonly int InstanceID; private static int NextInstanceID = 0; private static long ClassInstanceCount = 0;
Les variables membres InstanceCount et NextInstanceID étant déclarées comme static, elles n'existent qu'au niveau de la classe. Toutes les instances de CDemo qui accèdent à ces membres utilisent les mêmes emplacements en mémoire. Les membres statiques sont initialisés lorsque la première référence à la classe CDemo est rencontrée dans le code. Il peut s'agir de la première fois qu'un objet CDemo est créé ou du premier accès à l'un des membres statiques.
Localisez public CDemo() et public CDemo(IContainer container), les constructeurs par défaut de la classe CDemo. En Visual C#, tous les constructeurs portent le même nom que la classe. Votre composant peut avoir plusieurs constructeurs dotés de paramètres différents, mais ils doivent tous porter le nom que votre composant.
Notes
Le niveau d'accès aux constructeurs identifie les clients qui sont autorisés à créer des instances de la classe.
Ajoutez le code suivant à public CDemo() pour incrémenter le compteur d'instances lorsqu'une nouvelle instance de CDemo est créée et pour définir le numéro d'ID de l'instance.
Notes
Ajoutez toujours votre code après l'appel à InitializeComponent. À ce stade, tous les composants constitutifs sont initialisés.
InstanceID = NextInstanceID ++; ClassInstanceCount ++;
En tant que membre readonly , InstanceID ne peut être défini que dans le constructeur.
Notes
Les utilisateurs familiarisés avec le multithreading ne manqueront pas de noter, et à juste titre, que l'assignation de InstanceID et l'incrémentation de NextInstanceID devraient constituer une opération atomique. Ce point et d'autres problèmes en rapport avec le threading sont illustrés dans Procédure pas à pas : création d'un composant simple multithread à l'aide de Visual C#.
Ajoutez la méthode suivante à la fin du constructeur :
~CDemo() { ClassInstanceCount --; }
Cette méthode est appelée un destructeur et se caractérise par la présence d'un tilde (~) devant le nom de la classe. Le gestionnaire de mémoire appelle le destructeur juste avant de libérer la mémoire occupée par l'objet CDemo. En implémentant un destructeur, vous pouvez effectuer un nettoyage juste avant que le composant ne soit supprimé de la mémoire. Toutefois, comme vous le verrez par la suite, il existe de bonnes raisons pour libérer plus tôt les ressources.
Ajout d'une propriété à la classe
La classe CDemo ne possède qu'une seule propriété, une propriété statique qui permet au client de savoir à tout moment combien d'objets CDemo sont présents dans la mémoire. Des méthodes peuvent être créées de la même façon.
Pour créer une propriété pour la classe CDemo
Ajoutez la déclaration de la propriété suivante à la classe CDemo pour permettre aux clients de récupérer le nombre d'instances de CDemo.
public static long InstanceCount { get { return ClassInstanceCount; } }
Test du composant
Pour tester le composant, il vous faut un projet qui l'utilise. Ce projet doit être le premier qui démarre lorsque vous appuyez sur le bouton Exécuter.
Pour ajouter le projet client CDemoTest comme projet de démarrage de la solution
Dans le menu Fichier, pointez sur Ajouter et choisissez Nouveau projet pour ouvrir la boîte de dialogue Ajouter un nouveau projet.
Sélectionnez le modèle de projet Application Windows et tapez CDemoTest dans la zone Nom, puis cliquez sur OK.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur CDemoTest, puis cliquez sur Définir comme projet de démarrage dans le menu contextuel.
Pour utiliser le composant CDemo, le projet de test client doit posséder une référence au projet Bibliothèque de classes. La référence une fois ajoutée, il est judicieux d'ajouter une instruction using à l'application de test pour simplifier l'utilisation du composant.
Pour ajouter une référence au projet de bibliothèque de classes
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le nœud Références immédiatement sous CDemoTest, puis sélectionnez Ajouter une référence dans le menu contextuel.
Dans la boîte de dialogue Ajouter une référence, sélectionnez l'onglet Projets.
Double-cliquez sur le projet de bibliothèque de classes CDemoLib. CDemoLib apparaît sous le nœud Références du projet CDemoTest.
Dans l' Explorateur de solutions, cliquez avec le bouton droit sur Form1.cs et sélectionnez Afficher le code dans le menu contextuel.
L'ajout d'une référence à la bibliothèque de classes CDemoLib vous permet d'utiliser le nom complet du composant CDemo, à savoir CDemoLib.CDemo.
Pour ajouter une instruction using
Ajoutez l'instruction using suivante à la liste des instructions using affichée en haut de l'éditeur de code de Form1.
using CDemoLib;
L'ajout de l'instruction using vous permet d'omettre le nom de bibliothèque et de vous référer au type de composant en tant que CDemo.
Vous allez maintenant créer et utiliser un programme pour tester votre composant.
Concept de durée de vie d'un objet
Le programme CDemoTest illustre le concept de durée de vie d'un objet dans le .NET Framework en créant et libérant de nombreux objets CDemo.
Pour ajouter du code pour créer et libérer des objets CDemo
Cliquez sur Form1.cs[Design] pour revenir dans le concepteur.
Faites glisser Button et Timer de l'onglet Tous les Windows Forms de la Boîte à outils sur l'aire de conception de Form1.
Le composant non visuel Timer apparaît dans une aire de conception à part, sous le formulaire.
Double-cliquez sur l'icône de timer1 pour créer une méthode de gestion de l'événement Tick du composant timer1. Placez le code suivant dans la méthode de gestion d'événements.
this.Text = "CDemo instances: " + CDemo.InstanceCount;
À chaque graduation de la minuterie, la légende du formulaire affichera le nombre d'instances en cours de la classe CDemo. Le nom de la classe sert à qualifier la propriété InstanceCount statique (il n'est pas nécessaire de créer une instance de CDemo pour accéder à un membre statique).
Recherchez le constructeur de Form1 (public Form1()) et ajoutez le code suivant après l'appel à InitializeComponent().
timer1.Enabled = true;
Ainsi, la minuterie démarrera dès que le formulaire sera créé.
Cliquez sur Form1.cs[Design] pour revenir dans le concepteur.
Double-cliquez sur Button dans Form1, pour créer une méthode de gestion pour l'événement Click du bouton. Placez le code suivant dans la méthode de gestion d'événements.
CDemo cd; int ct; for (ct = 0; ct < 1000; ct++) cd = new CDemo();
Ce code peut vous sembler étrange. Chaque fois qu'une instance de CDemo est créée, l'instance précédente est libérée. Lorsque la boucle for se termine, il ne reste qu'une instance de CDemo. Lors de la sortie de la méthode de gestion d'événements, cette dernière instance est libérée elle aussi, parce que la variable cd passe hors de portée.
Comme vous l'avez probablement déjà deviné, les choses ne se passeront pas exactement ainsi.
Pour exécuter et déboguer les projets CDemoTest et CDemo
Appuyez sur F5 pour démarrer la solution.
Le projet client démarre et Form1 est affiché. Notez que la légende du formulaire affiche "CDemo instances: 0".
Cliquez sur le bouton. La légende du formulaire doit afficher "CDemo instances: 1000".
Les instances de CDemo ont toutes été libérées au moment où la procédure de gestion d'événement Click du bouton se termine. Pourquoi n'ont-elles pas été finalisées ? En bref, le gestionnaire de mémoire finalise les objets en arrière-plan avec une propriété basse. Le niveau de priorité n'est augmenté que si le système vient à manquer de mémoire. Ce dispositif minimal de garbage collection permet une allocation très rapide des objets.
Cliquez plusieurs fois sur le bouton en observant la légende. Vous voyez qu'à un moment le nombre d'instances chute brutalement. Cela indique que le gestionnaire de mémoire a libéré la mémoire de certains objets.
Notes
Si vous avez cliqué plus de 10 fois et que le nombre d'instances de CDemo n'a pas diminué, vous devrez peut-être modifier le code pour qu'il utilise davantage de mémoire. Fermez le formulaire pour revenir à l'environnement de développement et faites passer le nombre d'itérations de la boucle for à 10 000. Ensuite, réexécutez le projet.
Répétez l'étape 3. Vous irez plus loin cette fois-ci avant que le gestionnaire de mémoire ne finalise plus d'objets.
En fait, chaque fois que vous répéterez l'étape 3, vous pourrez allouer davantage d'objets CDemo avant que le gestionnaire de mémoire n'intervienne. En effet, une partie toujours plus importante de Visual Studio est permutée, ce qui laisse davantage d'espace aux instances de CDemo.
Fermez le formulaire pour revenir dans l'environnement de développement.