CasCap.Common.Services 5.2.0

Prefix Reserved
dotnet add package CasCap.Common.Services --version 5.2.0
                    
NuGet\Install-Package CasCap.Common.Services -Version 5.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CasCap.Common.Services" Version="5.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CasCap.Common.Services" Version="5.2.0" />
                    
Directory.Packages.props
<PackageReference Include="CasCap.Common.Services" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CasCap.Common.Services --version 5.2.0
                    
#r "nuget: CasCap.Common.Services, 5.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CasCap.Common.Services@5.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CasCap.Common.Services&version=5.2.0
                    
Install as a Cake Addin
#tool nuget:?package=CasCap.Common.Services&version=5.2.0
                    
Install as a Cake Tool

CasCap.Common.Services

Run selected .NET background features by name, observe their lifecycle and expose assembly-backed application metadata.

Installation

dotnet add package CasCap.Common.Services

Target frameworks: net10.0, net11.0

Usage

Register implementations as IBgFeature, then supply the enabled names to the launcher:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CasCap.Common.Abstractions;
using CasCap.Common.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddSingleton<IBgFeature, WorkerFeature>();
builder.Services.AddApplicationHostLifecycle(builder.Configuration);
builder.Services.AddFeatureFlagService(
    new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Worker" });

using var host = builder.Build();
await host.RunAsync();
return host.Services.GetApplicationExitCode();

public sealed class WorkerFeature(ILogger<WorkerFeature> logger) : IBgFeature
{
    public string FeatureName => "Worker";

    public async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            if (logger.IsEnabled(LogLevel.Debug))
                logger.LogDebug("{ClassName} poll completed", nameof(WorkerFeature));
            await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
        }
    }
}

Feature matching is case-insensitive. A feature named IBgFeature.AlwaysEnabled ("All") runs regardless of the selected set. Registration supplies IOptions<FeatureFlagConfig>; it does not automatically read an EnabledFeatures JSON section.

AddApplicationHostLifecycle binds CasCap:HostLifecycleConfig, configures HostOptions.ShutdownTimeout, and registers ApplicationExitState:

{
  "CasCap": {
    "HostLifecycleConfig": {
      "ShutdownTimeoutMs": 30000
    }
  }
}

Set the Kubernetes terminationGracePeriodSeconds longer than this timeout, including any PreStop duration and a safety margin.

UTC Cron Scheduling

CoalescingScheduleRunner in CasCap.Common.Services accepts a parsed Cronos expression, an injected TimeProvider, an awaited callback and a cancellation token. Five-field expressions use minute precision; seconds require explicit CronFormat.IncludeSeconds.

await CoalescingScheduleRunner.RunAsync(
    Cronos.CronExpression.Parse("0 * * * *"),
    TimeProvider.System,
    async (scheduledForUtc, token) => await RunJobAsync(scheduledForUtc, token),
    stoppingToken);

Occurrences are strictly after the cursor and use UTC. Each schedule runs sequentially; after completion, missed occurrences are coalesced rather than replayed. Startup/manual execution, distributed ownership, durable requests, retries and idempotency belong to the consumer. Cancellation stops pending delays and is passed into callbacks; callback failures propagate. RunWithTimeoutAsync cancels a cooperative operation and awaits its cleanup before reporting a timeout. It does not forcibly abandon work that ignores cancellation.

Feature Supervision Activity

  • No matching features is a startup failure.
  • A child may finish while siblings continue. Faults from enabled children propagate to the host.
  • If all children finish before cancellation, the launcher reports an unexpected lifecycle failure.
  • A finite job must request IHostApplicationLifetime.StopApplication() before returning.
  • Host cancellation cancels and awaits outstanding features, including their cleanup.
  • A child fault requests host shutdown immediately, then cancels and awaits its siblings before propagating the failure.
  • A child fault marks ApplicationExitState as failed before requesting shutdown. On .NET 10, the process entry point returns GetApplicationExitCode() after RunAsync to report a nonzero result.
  • On .NET 11 with BackgroundServiceExceptionBehavior.StopHost, Host.StopAsync and RunAsync rethrow background failures after cleanup. Preserve that failure at the process boundary rather than suppressing it; the exit state remains available for custom exception-handling entry points.
  • AddFeatureFlagService registers the exit state automatically. Call AddApplicationExitState() directly in hosts that also need to report startup or non-feature outcomes through the same process boundary.
  • A directly registered BackgroundService outside FeatureFlagBgService must mark the same state before requesting fatal shutdown, or use another supervisor that does.
  • Align host and container termination budgets for uncooperative cleanup.
flowchart TD
    HOST["Host startup"] --> MATCH["Match registered features against enabled names"]
    MATCH --> RUN["Run matching features and All features"]
    RUN --> WATCH["Observe child tasks"]
    WATCH -->|Child finishes, siblings remain| WATCH
    WATCH -->|Child faults or all finish without stopping| FAIL["Request host shutdown, cancel and await siblings, propagate failure"]
    WATCH -->|Host cancellation or requested stop| STOP["Cancel and await children, then clean shutdown"]

Configuration Examples

Feature Execution Only

The registration in Usage enables the selected features without periodic metadata logging.

Feature Execution with Metadata

Pass addApplicationMetadataService: true to register ApplicationMetadataBgService and ApplicationMetadata. The latter reads version, source revision and build context from assembly attributes, not live Git state.

builder.Services.AddFeatureFlagService(enabledFeatures, addApplicationMetadataService: true);

The optional metadata service binds ApplicationMetadataConfig. It writes one Information line with the repository, version, branch and commit at startup and then every LogInterval, which defaults to fifteen minutes and must be positive:

{
  "ApplicationMetadataConfig": {
    "LogInterval": "01:00:00"
  }
}
Product 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.  net11.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on CasCap.Common.Services:

Package Downloads
CasCap.Api.SignalCli

Typed .NET client for the signal-cli REST API with REST polling and JSON-RPC WebSocket transports, health checks, and INotifier integration.

CasCap.Common.OpenTelemetry

Reusable OpenTelemetry configuration with standard metrics, traces, and log exporters.

CasCap.Api.Voice

Provider-neutral speech-to-text and text-to-speech components for .NET applications.

CasCap.Common.Hosting.AspNetCore

ASP.NET Core hosting defaults for feature-gated controllers, Serilog, and OpenTelemetry metrics, traces, and logs.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.2.0 107 11/14/2026
5.1.0 426 11/5/2026
5.0.0 251 11/1/2026
4.17.0 343 10/24/2026
4.16.0 296 10/21/2026
4.15.0 161 10/6/2026
4.14.4 270 10/4/2026
4.14.3 168 9/28/2026
4.14.2 306 9/25/2026
4.14.1 369 9/23/2026
4.14.0 352 9/19/2026
4.13.0 151 9/15/2026
4.12.8 183 9/10/2026
4.12.7 152 9/4/2026
4.12.6 137 9/1/2026
4.12.5 149 8/20/2026
4.12.4 160 8/18/2026
4.12.3 165 7/15/2026
4.12.2 179 6/26/2026
4.12.1 172 6/14/2026
Loading failed