Getting Started
Installation
Install the NuGet package into the project that builds your host:
dotnet add package Invex.Extensions.Hosting
Supported frameworks
| Target | Notes |
|---|---|
| .NET 10 | |
| .NET 9 | |
| .NET 8 | Trimming/AOT annotations active from .NET 8 onward |
| .NET Standard 2.0 | Any runtime that supports Microsoft.Extensions.Hosting.Abstractions, including .NET Framework 4.8 (the test suite runs on net48 against this build) |
The only runtime dependency is Microsoft.Extensions.Hosting.Abstractions.
Namespaces
using Invex.Extensions.Hosting; // ServiceCollectionExtensions
using Invex.Extensions.Hosting.Control; // IHostControl, AddHostControl()
using Invex.Extensions.Hosting.Service; // CycleBackgroundService
A 5-minute tour
The example below shows all three features working together: a periodic worker that exposes a status interface, and that can shut the application down with an error exit code when something goes irrecoverably wrong.
using Invex.Extensions.Hosting;
using Invex.Extensions.Hosting.Control;
using Invex.Extensions.Hosting.Service;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// 1. IHostControl: graceful shutdown with an exit code.
builder.Services.AddHostControl();
// 2. Multi-interface hosted service registration: the SAME HealthWorker instance
// is the running hosted service AND the resolvable IHealthStatus.
builder.Services.AddHostedService<IHealthStatus, HealthWorker>();
await builder.Build().RunAsync();
// --- the worker ---
public interface IHealthStatus
{
bool IsHealthy { get; }
}
// 3. CycleBackgroundService: runs ExecuteCycleAsync every 5 seconds on a fixed cadence.
public sealed class HealthWorker(IHostControl hostControl) : CycleBackgroundService, IHealthStatus
{
private int _consecutiveFailures;
public bool IsHealthy => _consecutiveFailures == 0;
protected override int CycleCadenceMs => 5_000;
protected override async Task ExecuteCycleAsync(CancellationToken stoppingToken)
{
try
{
await CheckSomethingAsync(stoppingToken);
_consecutiveFailures = 0;
}
catch (Exception) when (++_consecutiveFailures >= 3)
{
// Give up: stop the host and report failure to the OS / orchestrator.
hostControl.StopApplication(exitCode: 1);
}
}
private static Task CheckSomethingAsync(CancellationToken ct) => Task.CompletedTask;
}
What each piece contributes:
AddHostControl()registersIHostControl, a superset ofIHostApplicationLifetimethat addsStopApplication(int exitCode).AddHostedService<TService, TImplementation>()registersHealthWorkeronce and forwardsIHealthStatusandIHostedServiceto that single instance — so a health endpoint can injectIHealthStatusand observe the live worker. See multi-interface registration.CycleBackgroundServicehandles the timing loop, so the worker only implements the per-cycle work. See cycle background service.