Service registration¶
This library registers no services of its own — it exposes two startup base classes a consumer inherits (ServiceProgramRunnerBase for the program entry point, ServiceWorker<T> for the recurring task loop) and resolves four services from the DI container that only SAIF.NetCore.ServiceExtensions's RegisterForWindowsService/RegisterForWindowsService<T> actually registers; a consuming Windows Service application must reference and call that companion method, or supply the same contracts itself through manual registration.
Registration extension catalog¶
This library defines no IServiceCollection/IHostBuilder extension methods itself. The extension methods below are owned and shipped by SAIF.NetCore.ServiceExtensions; they are documented here because this library's startup base classes and ServiceWorker<T> require their output to be present in the DI container at runtime. See SAIF.NetCore.ServiceExtensions overview for that library's own documentation. Using RegisterForWindowsService/RegisterForWindowsService<T> is the recommended way to satisfy those runtime contracts, but it is not the only way: ServiceWorker<T> and ServiceProgramRunnerBase only require that IWindowsServiceErrorHandler, ISaifWindowsServiceLogService, IEnvironmentClient, and IHttpJsonClient be resolvable from the container, however they get there — an equivalent set of manual registrations satisfies the same contracts without calling this specific extension method.
| Extension method | Hosting context | Parameters | Source |
|---|---|---|---|
RegisterForWindowsService<T>(this IServiceCollection services, bool registerSecureEnvironmentClient = true) where T : class |
worker (Windows service) | registerSecureEnvironmentClient (default true): when true, calls RegisterSecureEnvironmentClient(typeof(T)); when false, calls RegisterEnvironmentClient() (non-secure, registers ISystemHashService as a factory returning null). Always also registers ISaifWindowsServiceLogService, IWindowsServiceErrorHandler, and calls RegisterDBConnectionClient(). |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
RegisterForWindowsService(this IServiceCollection services) |
worker (Windows service) | No parameters; delegates to RegisterForWindowsService<object>(false) — always takes the non-secure EnvironmentClient path. |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
Overload-selection caveat:
RegisterDBConnectionClient()is called unconditionally by both overloads, always registeringIDBConnectionClientas a lazy singleton factory. That factory lambda (inSAIF.NetCore.ServiceExtensions, not insideConnectionClient) constructs its ownSystemHashService(typeof(ConnectionClient).Assembly)— it does not use the container-registeredISystemHashService— gets its hash, and callsIEnvironmentClient.GetSecureSettingto retrieve and split the connection credential before callingConnectionClient.SetupClientCredentials. On the non-secure path — either the parameterlessRegisterForWindowsService()overload, orRegisterForWindowsService<T>(false)—IEnvironmentClientresolves to the non-secureBaseEnvironmentClient, whoseGetSecureSettingthrowsEnvironmentClientException("Operation not allowed! This application is restricted from retrieving secure settings.") rather than failing with a null-reference error; the registered-but-unusednullISystemHashServicefactory is not involved in this failure. Prefer the generic overload with itstruedefault (or passtrueexplicitly) wheneverIDBConnectionClientwill be used.
Service registration catalog¶
These are the registrations made by the companion SAIF.NetCore.ServiceExtensions.RegisterForWindowsService<T>/RegisterForWindowsService calls this library depends on at runtime — none of them are registered by this library itself. A consumer may instead register the same contracts manually if it does not want the convenience call.
| Service type | Implementation | Lifetime | Registered by | Condition | Source |
|---|---|---|---|---|---|
IEnvironmentClient (+ ISystemWrapper, IHostResolver, IHttpJsonClient transient, ISystemHashService) |
SecureEnvironmentClient / BaseEnvironmentClient |
Singleton (IHttpJsonClient transient) |
RegisterSecureEnvironmentClient(typeof(T)) / RegisterEnvironmentClient() |
Gated by registerSecureEnvironmentClient; the non-generic RegisterForWindowsService() overload passes false, registering ISystemHashService as a factory returning null. |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
ISaifWindowsServiceLogService |
SaifWindowsServiceLog |
Singleton | RegisterForWindowsService<T> |
Always | src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
IWindowsServiceErrorHandler |
WindowsServiceErrorHandler |
Singleton | RegisterForWindowsService<T> |
Always | src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
IDBConnectionClient |
factory -> ConnectionClient (in SAIF.NetCore.DbConnectionClient) with secure credentials |
Singleton | RegisterDBConnectionClient() |
Always | src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs; src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs |
Startup base classes¶
Base classes a consuming application inherits to bootstrap its host.
| Base class | Inherits | Consumer type | Must implement | May override | Source |
|---|---|---|---|---|---|
ServiceProgramRunnerBase |
object |
Windows Service entry point (Program) |
None (no abstract members) | Run(string[]): creates the host once, then calls IHost.Run(). Create(string[]): builds the host, applies the optional delay, calls Configure. CreateHostBuilder(string[]): CreateDefaultBuilder + re-added appsettings.json + environment variables + UseWindowsService(). ConfigureErrorHandler(IWindowsServiceErrorHandler): empty by default. Configure(IHost): runs the error-handler hook, then ConfigureLogger. ConfigureLogger(IHost): calls ISaifWindowsServiceLogService.Configure(env, http). |
src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceProgramRunnerBase.cs |
ServiceWorker<T> (where T : IServiceTaskRunner) |
Microsoft.Extensions.Hosting.BackgroundService |
One consumer worker class per scheduled task | None (no abstract members) | ExecuteAsync (override): fixed-delay loop, immediate first run. RunTaskAsync: try/catch around TaskRunner.Run. HandleTaskError: exemption check, error-handler call, host stop. BuildErrorMessage: standard error-message text. Non-virtual: IsExceptionExemptFromShutdown. |
src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceWorker.cs |
Feature flags¶
Properties a consumer overrides, and environment variables a base class reads, that change registration or middleware behavior. Environment variables are also listed in Configuration.
| Name | Kind | Default | Effect | Source |
|---|---|---|---|---|
TaskDelayMilliseconds |
Property (ServiceWorker<T>) |
3000 | Delay after each task run, before the next iteration. | src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceWorker.cs |
ShutdownTimeoutSeconds |
Property (ServiceWorker<T>) |
30 | Graceful-stop timeout passed to ServiceHost.StopAsync on a fail-stop error. |
src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceWorker.cs |
DelayStart |
Environment variable / configuration key (process) | unset (no delay) | Blocks startup for N ms before the configuration hooks and IHost.Run(). |
src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceProgramRunnerBase.cs |
Hosted services and health checks¶
| Type | Kind | Registered by | Behavior | Source |
|---|---|---|---|---|
ServiceWorker<T> (abstract; consumer subclasses) |
BackgroundService |
The consumer, with services.AddHostedService<TWorker>() — this library does not register it |
Runs T.Run(stoppingToken) immediately, then every TaskDelayMilliseconds after completion. Catches all errors, reports them to IWindowsServiceErrorHandler, and stops the host unless the exception's exact runtime type is registered as shutdown-exempt and its predicate allows it. |
src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceWorker.cs |
There are no health checks or ping endpoints.
Required-but-not-registered services¶
Services this library's types resolve that none of its own methods add. The consuming application, or another library, must register them — in practice, by referencing SAIF.NetCore.ServiceExtensions and calling RegisterForWindowsService/RegisterForWindowsService<T>.
| Service type | Consumer | Expected source |
|---|---|---|
IServiceTaskRunner (concrete T) |
ServiceWorker<T> constructor |
The consumer app (e.g. AddTransient<IMyRunner, MyRunner>()) |
IWindowsServiceErrorHandler |
ServiceWorker<T> constructor; ServiceProgramRunnerBase.Configure (GetRequiredService) |
SAIF.NetCore.ServiceExtensions's RegisterForWindowsService → SAIF.NetCore.ErrorHandler's WindowsServiceErrorHandler (singleton) |
ISaifWindowsServiceLogService |
ServiceProgramRunnerBase.ConfigureLogger |
RegisterForWindowsService → SAIF.NetCore.Logging's SaifWindowsServiceLog (singleton) |
IEnvironmentClient |
ServiceProgramRunnerBase.ConfigureLogger |
RegisterForWindowsService → SAIF.NetCore.EnvironmentClient's BaseEnvironmentClient/SecureEnvironmentClient (singleton) |
IHttpJsonClient |
ServiceProgramRunnerBase.ConfigureLogger |
RegisterForWindowsService → SAIF.NetCore.HttpClients's HttpJsonClient (transient) |
IConfiguration |
ServiceProgramRunnerBase.DelayStartup |
Generic Host (always registered automatically) |
Related documentation¶
- Index
- Overview
- Architecture
- Dependencies
- Configuration
- Operations and processes
- Business rules
- API reference
Sources¶
src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService.csprojsrc/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceProgramRunnerBase.cssrc/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceWorker.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cssrc/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs