-
Notifications
You must be signed in to change notification settings - Fork 2
uml4net.Tools.project
The user manual of
uml4net.Tools
is here. This page covers the developer documentation
The uml4net.Tools
project is a commandline application using the System.CommandLine and System.CommandLine.Hosting infrastructure to create Commands and Options to enable the generation of reports. The report generators from the uml4net.Reporting project are used to generate the actual reports. The uml4net.Tools
project wraps them using Commands.
System.CommandLine provides essential functionality, such as parsing, invocation, and rendering support. The Command composition defines the structure and the way the app looks and feels. A ICommandHandler is assigned to a Command which is used during the invocation phase and provides model-binding functionality.
NOTE: System.CommandLine uses a naming convention to link command Options to Handler properties. Make sure the
name
of theOption
and the Handler option property are the same. Valid names would be:--no-logo
andNoLogo
(for the option.Name property and the Handler property).
For more information, please read the following articles, they were a great help to us:
- https://learn.microsoft.com/en-us/dotnet/standard/commandline/get-started-tutorial
- https://nikiforovall.github.io/dotnet/cli/2021/06/06/clean-cli.html
Each Command in the application derives from the abstract super class ReportCommand
. This command adds generic options that are valid for each derived command:
public abstract class ReportCommand : Command
{
protected ReportCommand(string name, string description = null) : base(name, description)
{
var noLogoOption = new Option<bool>(
name: "--no-logo",
description: "Suppress the logo",
getDefaultValue: () => false);
this.AddOption(noLogoOption);
var inputModelFileOption = new Option<FileInfo>(
name: "--input-model",
description: "The path to the UML XMI file",
getDefaultValue: () => new FileInfo("model.xmi"));
inputModelFileOption.AddAlias("-i");
inputModelFileOption.IsRequired = true;
this.AddOption(inputModelFileOption);
var pathMaps = new Option<string[]>(
name: "--pathmaps",
description: "Add pathmap key-value pairs");
pathMaps.AddAlias("-m");
pathMaps.AllowMultipleArgumentsPerToken = true;
this.AddOption(pathMaps);
var autoOpenReportOption = new Option<bool>(
name: "--auto-open-report",
description: "Open the generated report with its default application",
getDefaultValue: () => false);
autoOpenReportOption.AddAlias("-a");
autoOpenReportOption.IsRequired = false;
this.AddOption(autoOpenReportOption);
}
}
Each concrete Command (the following are provided: HtmlReportCommand
, MarkdownReportCommand
, ModelInspectionCommand
, XlReportCommand
) derives from ReportCommand
and sets its own Handler
to the abstract ReportHandler
. The abstract ReportHandler
handles invocation of the Command.
Any new Command needs to be added to the Commands project folder.
From the original documentation:
While each command has a handler that System.CommandLine will route to based on input, there's also a mechanism for short-circuiting or altering the input before your application logic is invoked. In between parsing and invocation, there's a chain of responsibility, which you can customize. A number of built-in features of System.CommandLine make use of this capability. This is how the --help and --version options short-circuit calls to your handler.
Currently one middleware is implemented which checks whether the most recent version of the application is being used, the VersionCheckerMiddleware
Middlware.
Any new middleware needs to be added to the Middlewares project folder.
Dependencies are wired up and injected in the Program.cs
class using the DI framework of .NET. The following need to be registered:
- services that are used to do work, i.e. generate reports
- Command and Command handlers
The following code snippet shows how the report generators and the commands are wired up:
public static int Main(string[] args)
{
var commandLineBuilder = BuildCommandLine()
.UseHost(_ => Host.CreateDefaultBuilder(args)
.ConfigureLogging(loggingBuilder =>
loggingBuilder.AddFilter<ConsoleLoggerProvider>(level =>
level == LogLevel.None))
, builder => builder
.ConfigureServices((services) =>
{
services.AddSingleton<IXlReportGenerator, XlReportGenerator>();
services.AddSingleton<IModelInspector, ModelInspector>();
services.AddSingleton<IHtmlReportGenerator, HtmlReportGenerator>();
services.AddSingleton<IMarkdownReportGenerator, MarkdownReportGenerator>();
})
.UseCommandHandler<XlReportCommand, XlReportCommand.Handler>()
.UseCommandHandler<ModelInspectionCommand, ModelInspectionCommand.Handler>()
.UseCommandHandler<HtmlReportCommand, HtmlReportCommand.Handler>()
.UseCommandHandler<MarkdownReportCommand, MarkdownReportCommand.Handler>()
)
.UseDefaults()
.Build();
return commandLineBuilder.Invoke(args);
}
copyright @ Starion Group S.A.