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.
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ément | Rôle |
|---|---|
LagoonConsoleApplication.Run<Main>(args) | Initialise et exécute l'application console Lagoon. |
Main | Porte la configuration applicative et la liste des sous-commandes. |
args | Contient les arguments transmis par la ligne de commande. |
int | Repré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.
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 Core | OnConfigureDbContext(DbContextOptionsBuilder builder) |
| Enregistrer les services métier | OnConfigureServices(IServiceCollection services) |
| Compléter l'affichage de statut | OnShowStatusAsync(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.
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ètre | Origine |
|---|---|
Main app | Instance de l'application console Lagoon. |
MyFooService fooService | Service 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
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).
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.