Skip to content

BaseTemplate DI Extensibility

Purpose

This page defines the internal implementation contract for DI orchestration extensibility between ConnectSoft.BaseTemplate and specialized templates (for example Identity).

Goals:

  • reduce duplicated startup/DI orchestration code
  • preserve BaseTemplate defaults as a stable baseline
  • allow targeted add/replace behavior through explicit hooks

Compile-time vs runtime: DI hooks affect runtime registration. MSBuild layering (Directory.Build.props, DisableMicrosoftExtensionsStackForMinimalHost.props in extended repos) and Central Package Management control which PackageReference items resolve and which ConnectSoft.Extensions.* optional stacks participate at build time (satellite Condition must match CPM PackageVersion conditions in ConnectSoft.BaseTemplate—see public MSBuild and Central Package Management / Option A). Bump the base-template/ submodule for fixes in Layer 2. See the public Template layering and reuse and ConnectSoft.Extensions catalog.

Standard terms used in this internal guide:

  • base + add
  • replace whole step
  • default-preserving hooks
  • submodule refresh

Core Model

Three-layer DI (outside in):

  1. ApplicationModelRegistrationBase (NuGet) — application-model registration shared across templates.
  2. MicroserviceRegistrationBase (base-template submodule) — default microservice registration flow and protected virtual hooks for derived templates.
  3. Template-specific registration — derived type in each specialized template overriding hooks as needed.

Host wiring:

  • MicroserviceRegistrationExtensions as host entry points
  • DefaultMicroserviceRegistration to preserve default BaseTemplate behavior
  • MicroserviceRegistrationBase protected virtual hooks for derived templates

Extension Patterns

base + add

Use when derived templates should keep base behavior and append custom registrations.

Examples:

  • extra localization resources
  • additional named/typed HTTP clients
  • template-specific metrics

replace whole step

Use when derived templates need different behavior for one registration stage.

Examples:

  • health check subset and tags
  • problem details mapping strategy
  • migration assembly routing and migrator registration

Hook Surface (high-level)

MicroserviceRegistrationBase includes hooks across:

  • registration staging before/after domain registration
  • cross-cutting concerns (localization, HTTP clients, metrics, security, rate limiting, header propagation, request timeouts, compression)
  • API stack (problem details, REST infra, Swagger, gRPC)
  • persistence/migrations (GetMigrationAssembly, fluent migrator registration, NH persistence)
  • observability and health checks
  • endpoint mapping and shutdown lifecycle

Extended Template Registration Classes

Each extended template provides a single registration coordinator class that inherits from MicroserviceRegistrationBase:

Template Registration Class
Identity IdentityMicroserviceRegistration
Auth Server AuthServerMicroserviceRegistration
Bot Framework BotFrameworkMicroserviceRegistration
API Gateway ApiGatewayMicroserviceRegistration
Health Checks Aggregator HealthChecksAggregatorRegistration
Microservice Template MicroserviceTemplateRegistration

Override Strategy

  • Replace: The override calls the template's static helper directly without calling base. Used when the template's method fully covers all registrations.
  • Base + Add: The override calls base.RegisterXxx(...) first, then appends template-specific registrations. Typically used for RegisterOptions and MapMicroserviceEndpoints.

Duplicate Extension Cleanup

Infrastructure-only extension files that duplicated base template functionality were removed from all extended templates (e.g., AzureAppConfigurationExtensions, CompressionExtensions, SerilogLoggingExtensions, etc.). These registrations are handled by MicroserviceRegistrationBase hooks.

OpenTelemetryAttributeName Consolidation

OpenTelemetryAttributeName.cs was removed from all extended templates. The type is sourced from ConnectSoft.Extensions.Observability NuGet.

Program.cs Alignment

All extended templates use the modern Serilog bootstrap pattern:

  • SerilogBootstrapExtensions.CreateBootstrapLogger() with #if Serilog guards
  • .UseSerilogBootstrap() in the host builder (replaces .UseSerilog(...))
  • Static Log.Information(...) / Log.Fatal(...) API (not instance Logger)
  • Azure App Configuration null-guard before options.Connect()

Test Infrastructure Alignment

  • TestStartup.ConfigureServices configures HealthCheckPublisherOptions with reduced delay (1s) and period (2s) for faster health status refresh in acceptance tests.
  • BeforeAfterTestRunHooks includes Azure App Configuration null-guard matching the Program.cs pattern.

Migration Checklist (Derived Templates)

  1. Identify duplicated DI orchestration in derived template ApplicationModel.
  2. Keep BaseTemplate default flow as source of truth.
  3. Move template-specific behavior to overrides in your template-specific registration class derived from MicroserviceRegistrationBase.
  4. Remove mostly identical orchestration code from derived template.
  5. Remove local copies of types available from shared NuGet packages (e.g., OpenTelemetryAttributeName).
  6. Align Program.cs to use SerilogBootstrapExtensions.CreateBootstrapLogger() with #if Serilog guards.
  7. Add Azure App Configuration null-guard in Program.cs and test BeforeAfterTestRunHooks.cs.
  8. Add HealthCheckPublisherOptions speed-up in TestStartup.ConfigureServices.
  9. Respect submodule boundaries:
    • do not edit submodule content directly
    • refresh submodule to consume BaseTemplate updates
  10. Verify with build + startup smoke checks (health, endpoints, middleware order).