Aller au contenu principal

Applications console Lagoon

Une application Batch Lagoon est une application console .NET qui démarre avec LagoonConsoleApplication.Run<Main>(args). Elle utilise Lagoon.Console, qui encapsule McMaster.Extensions.CommandLineUtils, pour déclarer des commandes en ligne de commande.

Dans l'application de démonstration, le projet Batch référence le modèle, les services et les commandes. La classe Main hérite de LgApplication<ApplicationDbContext> : il ne s'agit pas d'un hôte web, mais d'un point d'entrée console capable de configurer le DbContext, l'injection de dépendances et les sous-commandes.

Voir aussi l'architecture d'une solution Lagoon.

Point d'entrée​

Le fichier Program.cs reste volontairement court. Il transmet les arguments de la ligne de commande au framework Lagoon.

Program.cs
namespace Demo.Batch;

/// <summary>
/// The entry point of the application.
/// </summary>
internal class Program
{
/// <summary>
/// Application startup.
/// </summary>
/// <param name="args">The arguments.</param>
public static int Main(string[] args)
{
// Démarre l'application console Lagoon et retourne le code de sortie.
return LagoonConsoleApplication.Run<Main>(args);
}
}
ÉlémentRôle
LagoonConsoleApplication.Run<Main>(args)Initialise et exécute l'application console Lagoon.
MainPorte la configuration applicative et la liste des sous-commandes.
argsContient les arguments transmis par la ligne de commande.
intReprésente le code de sortie du processus.

Classe Main​

La classe Main configure l'application console et déclare les commandes disponibles avec [Subcommand]. Dans la démonstration, UpdateDbCommand est activée, tandis que BatchCommand est présente comme exemple à activer.

Main.cs
using Lagoon.Console.Application;
using Microsoft.EntityFrameworkCore;

namespace Demo.Batch;

/// <summary>
/// The console application's configuration and event manager.
/// </summary>
[Subcommand(typeof(UpdateDbCommand))]
// [Subcommand(typeof(BatchCommand))] <-- À décommenter pour activer la commande "batch".
public class Main : LgApplication<ApplicationDbContext>
{
/// <summary>
/// New instance handeling the Pierre-Fabre shared configuration.
/// </summary>
public Main() : base() { }

/// <summary>
/// Called when a main application DbContext need to be configured.
/// </summary>
/// <param name="builder">A builder used to create or modify options for the main database context.</param>
protected override void OnConfigureDbContext(DbContextOptionsBuilder builder)
{
// Réutilise la configuration du modèle pour cibler la bonne base de données.
ApplicationDbContext.Configure(builder, Configuration, ApplicationInformation.IsDevelopment);
}

/// <summary>
/// Register the services for the application.
/// </summary>
/// <param name="services">The service collection.</param>
protected override void OnConfigureServices(IServiceCollection services)
{
// Enregistre les services applicatifs disponibles pour les commandes.
Services.Registry.RegisterServices(services);
}

/// <summary>
/// Show the status of the application's resources.
/// </summary>
protected override Task OnShowStatusAsync(ShowStatusEventArgs e)
{
// Ajouter ici les contrôles de statut spécifiques à l'application.
return Task.CompletedTask;
}
}

Responsabilités de Main​

ResponsabilitéMéthode ou attribut
Démarrer les commandes connues[Subcommand(typeof(...))]
Configurer EF CoreOnConfigureDbContext(DbContextOptionsBuilder builder)
Enregistrer les services métierOnConfigureServices(IServiceCollection services)
Compléter l'affichage de statutOnShowStatusAsync(ShowStatusEventArgs e)

Déclarer une commande​

Une commande est une classe décorée avec [Command]. Ses options sont exposées par des propriétés décorées avec [Option]. Son exécution est portée par une méthode OnExecute ou OnExecuteAsync.

L'exemple suivant reprend le patron présent dans BatchCommand.cs.

BatchCommand.cs
namespace Demo.Batch.Commands;

/// <summary>
/// Execute the batch actions.
/// </summary>
[Command(Name = "batch", Description = "Batch actions.")]
public class BatchCommand
{
/// <summary>
/// Indicate if the batch must include the foo import.
/// </summary>
[Option("--import-foo", "Import the ...", CommandOptionType.NoValue)]
public bool ImportFooEnabled { get; set; }

/// <summary>
/// Execute the specified batch actions.
/// </summary>
/// <param name="app">The main application.</param>
/// <param name="fooService">The injected service that performs the foo import.</param>
public void OnExecute(Main app, MyFooService fooService)
{
// Affiche la version de l'application au début du traitement.
app.ShowVersion();

if (ImportFooEnabled)
{
// Le service est injecté automatiquement depuis les paramètres de méthode.
fooService.ImportFoo();
}

Console.WriteLine("Batch successfuly done !");
}
}

Injection de services dans OnExecute​

Lagoon suit le modèle McMaster : les services ne sont pas injectés par constructeur dans la commande. Ils sont résolus depuis les paramètres de OnExecute ou OnExecuteAsync.

ParamètreOrigine
Main appInstance de l'application console Lagoon.
MyFooService fooServiceService enregistré dans OnConfigureServices.

Le fichier _Usings.cs de la démonstration expose notamment les espaces de noms nécessaires aux commandes : Lagoon.Console.Application, Lagoon.Console.Commands, McMaster.Extensions.CommandLineUtils et Microsoft.Extensions.DependencyInjection.

Exécuter une commande​

Une fois la commande ajoutée à Main avec [Subcommand(typeof(BatchCommand))], elle devient accessible depuis l'exécutable Batch.

Demo.Batch batch --import-foo

Points d'attention​

Commandes et base de données

La configuration du DbContext du Batch doit correspondre à la base ciblée par le traitement. La démonstration réutilise ApplicationDbContext.Configure(builder, Configuration, ApplicationInformation.IsDevelopment).

Activation des commandes

Une classe décorée avec [Command] ne suffit pas à rendre la commande disponible. Elle doit être déclarée comme sous-commande, par exemple avec [Subcommand(typeof(BatchCommand))] sur Main.