Cet article a pour but de vous fournir un template d’initialisation pour réaliser une application console Windows C#. Il implémente des notions de programmation orientée objet et vous fournira je l’espère les outils et la réflexion nécessaires pour le déploiement d’applications futures. Nous allons également voir comment utiliser Visual Studio 2017 étape par étape pour arriver à nos fins.

Vous aurez besoin d’avoir à disposition les éléments suivants :

Une version de Visual Studio (https://www.visualstudio.com): la version « community », qui est gratuite, sera amplement suffisante pour la suite de cet article.

Postulat

Dans le cadre de la refonte des applications internes d’Ingéniance, une demande a été faite pour la mise en place d’outils liés à des tâches de mailing. Au-delà du fait que ces outils seront sujets à des tâches planifiées, il était surtout important de faire en sorte que ces outils, batch ou agents, qu’importe leur nom, aient une structure permettant une très bonne facilité de maintenance et de déploiement.

C’est là qu’entre en jeu la notion d’héritage de classe. L’idée est que nos agents vont tous hériter d’un socle commun donnant les outils nécessaires à leur bon fonctionnement.

Faisons l’inventaire du besoin :

  • Notre agent a besoin d’initialiser une tâche.
  • Notre agent a besoin de gérer son statut.
  • Notre agent a besoin de loguer des informations.
  • Notre agent a surtout besoin de s’exécuter.

Notre agent pourra bien sûr exécuter tout un tas d’autres tâches mais celles-ci feront déjà l’affaire.

Classe de base et sous-classe
La classe de base (ou classe mère) est celle qui définit les membres qui seront hérités par les sous-classes. Une sous-classe (ou classe fille) hérite des membres de la classe mère, peut ajouter de nouveaux membres, implémenter de nouvelles interfaces et redéfinir le comportement des méthodes de la classe de base.

Lorsqu’une classe ne déclare aucune classe de base, par défaut elle hérite de la classe System.Object. La classe System.Object est la seule qui n’hérite d’aucune autre classe.

Création du projet « Agent »

Nous allons procéder étape par étape dans la réalisation de notre application console Windows C#.

  • Depuis Visual Studio, créez un nouveau projet (Ctrl+Maj+N) de type « Application console (.NET Framework) » dans la rubrique C#.

Afin que tous nos agents héritent de la même classe de base, nous allons créer un deuxième projet qui distribuera celle-ci.

Cela nous permettra de déployer facilement dans n’importe quel projet une DLL contenant notre classe.

  • Ajoutez un nouveau projet mais cette fois de type « Bibliothèque de classe (.NET Framework) ». N’oubliez pas de nommer et de sélectionner « Ajouter à la solution » votre nouveau projet.

Règle de nommage des espaces de nom
La règle générale utilisée pour le nommage des espaces de nom ou « namespaces » est d’utiliser le nom de la société suivie par le nom de la technologie et éventuellement la fonctionnalité et le design comme suit :
CompanyName.TechnologyName[.Feature][.Design]
Utilisez la casse Pascal comme règle générale, ou mettez tout en majuscule pour les très petits mots :
System.Windows.Forms, System.Web.UI

  • Afin de gagner en visibilité dans notre DLL, nous allons répartir les fonctionnalités dans différents dossiers. Créez deux dossiers, le premier que l’on nommera « Agent » et qui contiendra notre classe de base, et le deuxième « Énumérations » qui contiendra comme son nom l’indique des énumérations (pouvant gérer le statut de notre agent par exemple). Pour cela, faites un clic droit sur l’intitulé de votre nouveau projet dans l’onglet « Explorateur de solution » et faites : Ajouter > Nouveau dossier.
  • Vous pouvez maintenant supprimer la classe par défaut (class1.cs) créée lors du nouveau projet, puis ajouter une nouvelle classe dans le dossier « Agent » que vous nommerez comme suit : AgentBase.cs. Faites un clic droit sur le dossier « Agent » puis : Ajouter > Classe…
  • La dernière chose à faire est de créer une référence de notre DLL à notre projet Agent afin de pouvoir en hériter. Retournez dans le projet Agent, et faites un clic droit sur l’élément « Références » > Ajouter une référence > Sélectionnez « Projet » et cocher le nom du projet correspondant à votre DLL.

Implémentation de la classe de base

Nous allons maintenant procéder à l’implémentation de notre classe héritée. Le but de cette classe est avant tout d’amener une structure et une implémentation par défaut à n’importe lequel de nos agents. Nous allons donc commencer par la déclarer Abstract, puis fournir l’ensemble des méthodes que chaque agent se doit d’implémenter. Dans les faits nous en avons peu pour le moment, mais rien n’empêche par la suite d’étendre la liste.

public abstract class AgentBase
{
    /// <summary>
    /// Run the instance.
    /// </summary>
    /// <param name="args">The arguments</param>
    public void Run(params string[] args)
    {
        // Does the job.
        this.DoWork(args);
    }
  
    /// <summary>
    /// Does the work.
    /// </summary>
    /// <param name="args">The arguments.</param>
    protected abstract void DoWork(params string[] args);
}

Notre implémentation prévoit donc une méthode Run disposant d’une implémentation par défaut ainsi qu’une méthode abstraite DoWork exécutée dans Run. Nous allons à présent l’en faire hériter par un agent dans le projet Agents. Vous verez ainsi l’intérêt de l’abstraction.

Héritage

Rajoutez une nouvelle classe dans le projet Agent. Pour ajouter une référence à une DLL externe au projet dans cette nouvelle classe, il faut utiliser le terme using suivi de l’espace de nom. Ce qui nous donne :

namespace Agents
{
    using Ingeniance.Core.Agent;
  
    public class Agent : AgentBase
    {
    }
}

Notez la notion d’héritage à la classe AgentBase par la classe Agent via la syntaxe « : ». Ici, Visual Sudio doit vous indiquer une erreur d’implémentation, mais vous permet de la corriger si vous cliquez sur l’ampoule à gauche du code en erreur :

Votre agent dispose maintenant d’une structure héritée par la classe AgentBase.

namespace Agents
{
    using Ingeniance.Core.Agent;
  
    public class Agent : AgentBase
    {
        protected override void DoWork(params string[] args)
        {
            // throw new System.NotImplementedException();
        }
    }
}

Vous pouvez modifier le code non implémenté par celui que votre agent est censé exécuter (pour les besoins de cet article, pensez à commenter le retour d’erreur). C’est bien beau tout ça, mais comment on exécute l’agent depuis notre console Windows ?

Exécution

Lors de la création de notre projet console Windows Agent, Visual Studio a ajouté une classe Program.cs qui contient la méthode statique Main. Cette méthode représente le point d’entrée de votre application, mais peut être paramétrée depuis une fenêtre de configuration disponible depuis les propriétés du projet :

Vous devez à présent modifier la méthode Main pour qu’elle appelle la méthode Run de l’agent, héritée de la classe de base AgentBase.

namespace Agents
{
    class Program
    {
        static void Main(string[] args)
        {
            new Agent().Run(args);
        }
    }
}

Notez la présence des arguments en paramètre de notre méthode Run. Vous avez ainsi l’avantage de pouvoir récupérer les arguments passés en ligne de commande de votre application console vers votre classe de base. Nous allons en tirer parti dans ce qui suit.

Conclusion

Grâce à l’héritage et à l’abstraction vous êtes en mesure de fournir une structure et une implémentation par défaut à l’ensemble de vos applications s’appuyant sur un même contexte. Si vous avez besoin de mettre en place un audit de vos applications, il vous suffit de l’implémenter dans la classe de base. A l’inverse, les actions métiers pourrons être développées depuis la méthode abstraite DoWork dans chacun des agents.

L’ensemble du code source est disponible depuis la répo GitHub suivante: CSharp-Console-With-Base-Class

Tips

Si vous avez exécuté votre programme, vous n’aurez probablement pas eu le temps de voir grand-chose à part une fenêtre qui se ferme. Pour stopper l’exécution, nous pourrions lui passer un paramètre pour qu’il attende une action utilisateur. La première chose à faire est de paramétrer cette action uniquement en « debug » dans le cas d’une exécution depuis notre environnement de développement.

Allez dans les propriétés du projet « Agent », puis dans l’onglet « Déboguer ». Dans la partie « Options de démarrage », ajouter « console » dans la zone de texte :

Modifiez ensuite le contenu de la méthode Run de la classe AgentBase comme suit :

public void Run(params string[] args)
{
    // Does the job.
    this.DoWork(args);
  
    if (args != null && args.Any(a => string.Equals(a, "console", StringComparison.OrdinalIgnoreCase)))
    {
        Console.WriteLine("Press enter to quit. ");
        Console.ReadLine();
    }
}

Le test vérifie la présence d’un argument correspondant au terme « console ». Dans le cas d’une égalité, on écrit une ligne dans la console demandant un retour utilisateur.

Sources

Retrouvez l’ensemble du code source ainsi que quelques aménagements pour la gestion des logs et du statut dans les liens ci-dessous :


0 commentaire

Laisser un commentaire

Avatar placeholder

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Application console C# avec classe de base

par Cyrille P. temps de lecture : 6 min
0