AceWorks.Tools
2026.9.11
dotnet add package AceWorks.Tools --version 2026.9.11
NuGet\Install-Package AceWorks.Tools -Version 2026.9.11
<PackageReference Include="AceWorks.Tools" Version="2026.9.11" />
<PackageVersion Include="AceWorks.Tools" Version="2026.9.11" />
<PackageReference Include="AceWorks.Tools" />
paket add AceWorks.Tools --version 2026.9.11
#r "nuget: AceWorks.Tools, 2026.9.11"
#:package AceWorks.Tools@2026.9.11
#addin nuget:?package=AceWorks.Tools&version=2026.9.11
#tool nuget:?package=AceWorks.Tools&version=2026.9.11
Ace.Tools
Common utilities and interactive maintenance tooling for .NET applications.
Ace.Tools may be used freely in commercial, personal, and open-source projects under The Unlicense.
Namespaces
| Namespace | Description |
|---|---|
Ace.Tools.Common |
General-purpose machine and processing utilities. |
Ace.Tools.Maintenance |
Interactive maintenance actions, host startup integration, console presentation, and supporting infrastructure. |
Maintenance
Ace.Tools.Maintenance provides an interactive maintenance menu. Actions are discovered from loaded assemblies and resolved through dependency injection.
Maintenance can run in two modes:
- Bootstrap maintenance runs before the application host is built. Use it for self-contained diagnostics that do not require application services.
- Hosted maintenance runs during ordered host startup. It can use the application's dependency injection container and infrastructure started before the maintenance module.
Bootstrap maintenance
Run bootstrap maintenance before building the application host:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
await Startup.RunBootstrapMaintenanceAsync();
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((_, services) =>
{
services.AddMemoryCache();
services.AddHostedService<SomeLongRunningService>();
})
.Build();
await host.RunAsync();
Only maintenance actions that also implement IBootstrapMaintenanceAction are available in bootstrap mode.
Bootstrap actions must remain self-contained because the application service provider does not exist yet.
Hosted maintenance
Register the maintenance module before hosted workloads that must wait for maintenance to complete:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((_, services) =>
{
// Infrastructure available to maintenance actions.
services.AddMemoryCache();
// Maintenance acts as an ordered startup barrier.
services.AddMaintenanceModule();
// Active workloads start after maintenance completes.
services.AddHostedService<SomeLongRunningService>();
})
.Build();
await host.RunAsync();
When startup maintenance is enabled, hosted-service registration order is significant:
- Hosted infrastructure registered before
AddMaintenanceModule()starts first. - The maintenance module pauses startup and displays the maintenance prompt.
- If requested, actions run using the application service provider.
- Hosted services registered after
AddMaintenanceModule()start when the maintenance session ends.
This allows maintenance actions to use application infrastructure without starting normal background workloads at the same time.
Hosted-service startup must remain sequential for this ordering guarantee. The maintenance module configures HostOptions.ServicesStartConcurrently accordingly; applications should not override it.
Creating a maintenance action
Apply MaintenanceActionAttribute to a concrete IMaintenanceAction implementation:
[MaintenanceAction("Run Simulation Check 🧪")]
public sealed class SimulationCheck : MaintenanceActionBase
{
public override async ValueTask RunAsync(MaintenanceContext context, CancellationToken ct = default)
{
ArgumentNullException.ThrowIfNull(context);
SimulationEngine engine = context.Services.GetRequiredService<SimulationEngine>();
await engine.RunCheckAsync(ct);
}
}
MaintenanceContext.Services is scoped to the maintenance session. Use it to resolve scoped application services.
To make an action available during bootstrap maintenance, also implement IBootstrapMaintenanceAction:
[MaintenanceAction("View Embedded Resources 📦🧾")]
public sealed class EmbeddedResourceInventory : MaintenanceActionBase, IBootstrapMaintenanceAction
{
public override ValueTask RunAsync(MaintenanceContext context, CancellationToken ct = default)
{
ArgumentNullException.ThrowIfNull(context);
ct.ThrowIfCancellationRequested();
// Perform the maintenance action.
return ValueTask.CompletedTask;
}
}
Bootstrap actions must not depend on services registered by the application host.
Action discovery
Maintenance actions are discovered from assemblies already loaded into the current application domain.
Register assemblies loaded later explicitly:
services.AddMaintenanceActionsFromAssembly(typeof(SimulationCheck).Assembly);
Dynamic assemblies are ignored. Discovered actions are ordered first by their configured action order and then by stable type name.
Action menu grouping
Maintenance actions may be grouped into nested menu folders either explicitly or by namespace.
Explicit menu levels take precedence over namespace-derived grouping. Slash-separated explicit menu levels create nested folders.
Actions without an explicit menu level are grouped from the portion of their namespace below:
.Maintenance.Actions.
For example:
| Action namespace | Menu location |
|---|---|
MyApp.Maintenance.Actions.Database |
Database |
MyApp.Maintenance.Actions.Database.Indexes |
Database / Indexes |
MyApp.Maintenance.Actions.Cache |
Cache |
MyApp.Tools.Diagnostics |
Root menu |
| No namespace | Root menu |
Namespaces that do not contain .Maintenance.Actions. are not forced into an Other folder. They are displayed directly in the root maintenance menu.
If you want an action to appear in an Other folder, place it there explicitly using the action's configured menu level.
So your README would continue from the end like this:
```md
Dynamic assemblies are ignored. Discovered actions are ordered first by their configured action order and then by stable type name.
### Action menu grouping
Maintenance actions may be grouped into nested menu folders either explicitly or by namespace.
Explicit menu levels take precedence over namespace-derived grouping. Slash-separated explicit menu levels create nested folders.
Actions without an explicit menu level are grouped from the portion of their namespace below:
```text
.Maintenance.Actions.
For example:
| Action namespace | Menu location |
|---|---|
MyApp.Maintenance.Actions.Database |
Database |
MyApp.Maintenance.Actions.Database.Indexes |
Database / Indexes |
MyApp.Maintenance.Actions.Cache |
Cache |
MyApp.Tools.Diagnostics |
Root menu |
| No namespace | Root menu |
Namespaces that do not contain .Maintenance.Actions. are not forced into an Other folder. They are displayed directly in the root maintenance menu.
If you want an action to appear in an Other folder, place it there explicitly using the action's configured menu level.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection (>= 10.0.11)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.11)
- Microsoft.Extensions.Hosting (>= 10.0.11)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.11)
- Spectre.Console (>= 0.57.2)
- Spectre.Console.ImageSharp (>= 0.57.2)
- System.Security.Cryptography.ProtectedData (>= 10.0.11)
- System.ServiceProcess.ServiceController (>= 10.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.