Skip to content

Repository files navigation

Lifecycle.NET

.NET License: MIT Status: Alpha GitHub Pages

Lifecycle.NET logo

Lifecycle.NET is an async-first, framework-independent lifecycle foundation for .NET services and components. It standardizes initialization, startup, pausing, stopping, restart, disposal, and dependency-aware orchestration.

NuGet packages use the Magnexis.Lifecycle.* namespace to provide a unique, publisher-owned package identity. This does not change the Lifecycle C# namespaces or the Lifecycle.NET product name.

Install

dotnet add package Magnexis.Lifecycle --version 0.1.0-alpha.1

Official NuGet package: nuget.org/packages/Magnexis.Lifecycle

Lifecycle.NET is currently an alpha release. Pin the prerelease version explicitly and test it in a non-critical environment before adopting it in production.

Official package page: nuget.org/packages/Magnexis.Lifecycle/0.1.0-alpha.1

Package identity change

The initial package identifiers (Lifecycle.NET, Lifecycle.Graph, and related IDs) were not available for publication on NuGet.org. The published family therefore uses a Magnexis-owned prefix:

Earlier package ID Published package ID
Lifecycle.NET Magnexis.Lifecycle
Lifecycle.Abstractions Magnexis.Lifecycle.Abstractions
Lifecycle.Graph Magnexis.Lifecycle.Graph
Lifecycle.Diagnostics Magnexis.Lifecycle.Diagnostics
Lifecycle.Hosting Magnexis.Lifecycle.Hosting
Lifecycle.Extensions.DependencyInjection Magnexis.Lifecycle.Extensions.DependencyInjection

This is a NuGet package-ID change only. Existing using Lifecycle; directives, assembly names, project names, and public API namespaces remain unchanged.

Included today

  • Thread-safe LifecycleObject base class with validated states and serialized transitions.
  • Cancellation tokens and configurable startup/shutdown timeouts.
  • Transition events, WaitForStateAsync, health signals, and middleware.
  • Dependency graph orchestration with structured validation, immutable execution snapshots, dry runs, bounded parallel waves, atomic rollback, reverse shutdown, and Mermaid export.
  • Microsoft.Extensions.DependencyInjection registration extensions.
  • .NET Generic Host integration with deterministic startup and reverse-order shutdown.
  • Bounded diagnostics history, aggregate metrics, and retry middleware for transient transition failures.
  • A supervisor that can observe failed objects, invoke recovery, and safely restart them.
  • Work leases and drain barriers for graceful pauses, restarts, shutdowns, and disposal.
  • A self-contained executable test suite requiring no third-party test runner.

Common package combinations

Need Package
Lifecycle base class and middleware Magnexis.Lifecycle
Contracts only Magnexis.Lifecycle.Abstractions
Dependency-aware startup and rollback Magnexis.Lifecycle.Graph
History, metrics, and recovery supervision Magnexis.Lifecycle.Diagnostics
IServiceCollection registration Magnexis.Lifecycle.Extensions.DependencyInjection
.NET Generic Host coordination Magnexis.Lifecycle.Hosting

Quick start

using Lifecycle;

public sealed class Worker : LifecycleObject
{
    protected override Task OnStartAsync(CancellationToken cancellationToken)
    {
        // Start resources here.
        return Task.CompletedTask;
    }

    protected override Task OnStopAsync(CancellationToken cancellationToken)
    {
        // Release active work here.
        return Task.CompletedTask;
    }
}

var worker = new Worker();
await worker.InitializeAsync();
await worker.StartAsync();
await worker.WaitForRunningAsync();
await worker.StopAsync();

Graceful work draining

Acquire a lease around active work. During a pause, restart, shutdown, or disposal, Lifecycle.NET stops accepting new leases and waits for active leases to complete.

await using var lease = await worker.AcquireLeaseAsync(cancellationToken);
await ProcessMessageAsync(cancellationToken);

Recovery supervision

RecoverAsync() is valid after a lifecycle enters Failed and returns it to Initialized. Add an opt-in supervisor when a failed component should be recovered and restarted automatically.

using var supervisor = new Lifecycle.Diagnostics.LifecycleSupervisor();
supervisor.Supervise(worker);

State model

Created → Initializing → Initialized → Starting → Running → Pausing → Paused → Resuming → Running → Stopping → Stopped

Failures enter Failed; RecoverAsync transitions through Recovering back to Initialized; disposal reaches Disposed. Invalid operations throw LifecycleTransitionException before a hook runs.

Transactional orchestration

var graph = new Lifecycle.Graph.LifecycleGraphBuilder()
    .Add("database", database)
    .Add("cache", cache, "database")
    .Add("api", api, "database", "cache")
    .Build();

var dryRun = await graph.DryRunStartAsync();
await using var transaction = graph.BeginTransaction("application-startup");
var result = await transaction.StartAsync();

if (!result.Succeeded)
    throw result.Failure!;

Build and test

dotnet build Lifecycle.NET.sln --configuration Release
dotnet run --project tests/Lifecycle.Tests -c Release

Create NuGet packages

Lifecycle.NET uses SDK-style project metadata rather than separate .nuspec files, keeping package metadata aligned with each library project. To create local prerelease packages and symbol packages:

dotnet pack Lifecycle.NET.sln --configuration Release --output ./artifacts/packages

Packages include the official logo and package README. Publishing uses NuGet Trusted Publishing through GitHub Actions OIDC; no long-lived API key is stored in this repository.

Documentation site

The static documentation site lives in docs/site and is deployed by the GitHub Pages workflow. Before its first deployment, a repository administrator must enable GitHub Pages and select Pages → Build and deployment → Source → GitHub Actions. Subsequent pushes to main that change documentation or branding deploy it automatically.

Alternatively, add a PAGES_ENABLEMENT_TOKEN repository secret containing a fine-grained token with Pages: write and Administration: write for this repository. The workflow then enables Pages on its first run. Do not use a broad personal token or expose the token in workflow files.

Architecture

Project Responsibility
Lifecycle.Abstractions State, contracts, events, middleware contracts, options, exceptions.
Lifecycle.NET Lifecycle engine, hook invocation, pipeline, timeout enforcement.
Lifecycle.Graph Dependency graph validation and orchestration.
Lifecycle.Diagnostics Bounded transition history and aggregate in-process metrics.
Lifecycle.Hosting Standard .NET Generic Host bridge.
Lifecycle.Extensions.DependencyInjection DI service registration.

Roadmap

The next slices are intentionally not placeholders: reusable lifecycle plans, optional/conditional dependencies, policy engine circuit breaking, checkpoints, safe replacement, health/readiness adapters, OpenTelemetry, platform adapters, testing helpers, and the Roslyn source generator will be added with their actual integration tests and package metadata.

License

MIT. See LICENSE.

About

Lifecycle.NET is an async-first, framework-independent lifecycle foundation for .NET services and components. It standardizes initialization, startup, pausing, stopping, restart, disposal, and dependency-aware orchestration.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Sponsor this project

Packages

Contributors

Languages