Template Architecture Specification¶
This document provides a comprehensive technical specification for ConnectSoft's template architecture. It serves as the authoritative contract for how templates are structured, how they inherit and compose functionality, and the mechanisms for extension at both build-time and generation-time. It is written for architects, engineers, and developers involved in template development and usage.
Document Purpose¶
This specification provides:
- Complete technical contract for template hierarchy and inheritance
- Rules and mechanisms for template JSON/CLI inheritance
- Build-time vs generation-time extension patterns
- Reference wiring mechanisms for tests, docs, and infrastructure
- Authoritative source for template developers
Template Hierarchy & Inheritance¶
ConnectSoft templates follow a three-layer model to ensure maximum reuse, consistency, and flexibility.
Base Microservice Template¶
The foundational layer, providing the core structure and common infrastructure for all microservices. It is domain-agnostic.
Structure: Includes projects for Host, Domain (base entities/value objects), Application (base interfaces), Infrastructure (base persistence/messaging setup), and Tests (base testing infrastructure).
Responsibilities: Bootstrapping, common health checks, resilience patterns, base CI/CD, base documentation structure, and canonical template.json metadata.
Specialized Templates (Overlays)¶
These templates add domain-specific functionality on top of the base template. Examples include Identity, Auth Server, Audit, and Worker templates.
Structure: Each specialized template is its own repository, including the base template as a Git submodule. It adds domain-specific projects (e.g., Identity.Api, Identity.Domain, Identity.Infrastructure), domain-specific tests, and domain-specific documentation.
Composition: At generation time, these specialized templates act as "overlays" that are applied to the base template.
Multi-Overlay Composition¶
Multiple overlays can be composed to create highly specialized services. For example, an Identity Backend with Worker functionality.
flowchart TD
Layer1[Shared Libraries<br/>(NuGet Packages)] --> Layer2[Base Microservice Template<br/>(Git Submodule)]
Layer2 --> Layer3A[Identity Backend Template<br/>(Overlay)]
Layer2 --> Layer3B[Auth Server Template<br/>(Overlay)]
Layer2 --> Layer3C[Worker Template<br/>(Overlay)]
Layer3A --> Composed[Composed Template:<br/>Base + Identity]
Layer3A & Layer3C --> MultiComposed[Composed Template:<br/>Base + Identity + Worker]
subgraph TemplateHierarchy[Template Hierarchy]
Layer1
Layer2
Layer3A
Layer3B
Layer3C
end
Template Folder Structure & Organization¶
Templates are organized to support both independent development and automated composition.
Base Template Folder Structure (MicroserviceTemplate.Base/)¶
MicroserviceTemplate.Base/
├── src/ # Core source code projects (Host, Domain, Application, Infrastructure)
├── tests/ # Base testing infrastructure (Base.Testing.Infrastructure)
├── docs/ # Base documentation (overview.md, architecture.md)
└── template/ # Template metadata for dotnet new
├── template.json # Canonical template parameters
├── ide.host.json # IDE-specific host configuration
└── dotnetcli.host.json # CLI-specific host configuration
Specialized Template Folder Structure (IdentityBackendTemplate/)¶
IdentityBackendTemplate/
├── .gitmodules # Defines git submodule for base-template
├── base-template/ # Git submodule pointing to MicroserviceTemplate.Base
│ ├── src/ # Base source code
│ ├── tests/ # Base tests
│ └── docs/ # Base docs
├── src/ # Identity-specific source code (Identity.Api, Identity.Domain, etc.)
├── tests/ # Identity-specific tests (Identity.UnitTests, Identity.AcceptanceTests)
├── docs/ # Identity-specific documentation (identity-overview.md, identity-auth-flows.md)
└── template/ # Overlay metadata
├── identity.template.extend.json # Extends base template.json for Identity
└── worker.template.extend.json # Optional: Extends for Worker functionality
Template JSON Inheritance System¶
The template.json files define the parameters and post-actions for dotnet new templates. Inheritance is managed through "extend files" and a merge process.
Base template.json¶
Defines canonical parameters, classifications, tags, and post-actions common to all microservices.
Extend Files (*.template.extend.json)¶
Specialized templates use extend files to:
- Override top-level fields (name, shortName, description).
- Override existing symbols (parameters) like
defaultValue,description. - Add new domain-specific symbols (e.g.,
UseExternalIdp,RequireEmailConfirmation). - Add additional
postActions(e.g., running domain-specific migrations). - Add additional
primaryOutputs.
Rules for Overriding and Inheritance¶
- Must Inherit: Core infrastructure parameters (e.g.,
ServiceName,RootNamespace,PersistenceType,MessagingType) must always be present in the finaltemplate.json. Specialized templates can override their default values or descriptions but cannot remove them. - Can Override:
name,shortName,description,tags,classifications, and properties of existing symbols (e.g.,defaultValue,displayName,description,choices). - Can Add: New symbols, post-actions, and primary outputs specific to the specialized template.
- Cannot Remove: Existing symbols or post-actions from the base template.
Merge Process Flow¶
The pack-template.ps1 script orchestrates the merging of template.json and extend files.
flowchart TD
BASE_JSON[Base template.json]
IDENTITY_EXTEND[identity.template.extend.json]
WORKER_EXTEND[worker.template.extend.json]
MERGE_PROCESS[Template Metadata Merge Process]
BASE_JSON --> MERGE_PROCESS
IDENTITY_EXTEND --> MERGE_PROCESS
WORKER_EXTEND --> MERGE_PROCESS
MERGE_PROCESS --> APPLY_OVERRIDES[Apply identityOverrides]
APPLY_OVERRIDES --> APPLY_SYMBOL_OVERRIDES[Apply symbolOverrides]
APPLY_SYMBOL_OVERRIDES --> APPLY_SYMBOL_ADDS[Apply symbolAdds]
APPLY_SYMBOL_ADDS --> APPLY_POST_ACTIONS[Apply postActionsAdds]
APPLY_POST_ACTIONS --> APPLY_PRIMARY_OUTPUTS[Apply primaryOutputsAdds]
APPLY_PRIMARY_OUTPUTS --> FINAL_JSON[Final Composed template.json]
IDE & CLI Configuration Inheritance¶
Similar to template.json, ide.host.json and dotnetcli.host.json also support inheritance.
ide.host.json: Provides IDE-specific configurations (e.g., default project to open, debug profiles). Specialized templates can extend this to add domain-specific debug profiles or settings.dotnetcli.host.json: Provides CLI-specific configurations (e.g., default arguments fordotnet new). Specialized templates can extend this to add domain-specific CLI options.
Configuration Merge Rules¶
- JSON Patching: Configurations are merged using a JSON Patch-like mechanism, where properties from extend files override or add to properties in the base configuration.
- Arrays: Arrays are typically appended or replaced, depending on the specific configuration section.
- Override vs. Extend: Explicit rules define whether a section is fully replaced (override) or incrementally added to (extend).
Build-Time vs Generation-Time Extension¶
ConnectSoft templates are designed for a dual-mode approach.
Build-Time Extension (Developer Experience)¶
- Mechanism: Git submodules are used to include the base template directly within specialized template repositories.
- Solution File Composition: The specialized template's
.slnfile includes projects from both the base template and the specialized template. - Project References: Specialized projects directly reference base projects (e.g.,
Identity.DomainreferencesBase.Domain). - Test Projects: Base provides generic testing infrastructure (e.g.,
Base.Testing.Infrastructure), which specialized templates reference and extend (e.g.,Identity.AcceptanceTestsusesBase.Testing.Infrastructure). - Documentation: Base documentation is available via the submodule, and specialized documentation extends this structure.
- Metrics/Options Libraries: Base provides extension points (
IMetricsFeature,IConfigureOptions<T>) that specialized templates implement.
graph TD
SUBGRAPH_REPO[Specialized Template Repository<br/>(e.g., IdentityBackendTemplate)]
SUBMODULE[Git Submodule<br/>(MicroserviceTemplate.Base)]
SPECIALIZED_SRC[Specialized Source Code<br/>(Identity.Api, Identity.Domain)]
SPECIALIZED_TESTS[Specialized Tests<br/>(Identity.AcceptanceTests)]
SOLUTION_FILE[IdentityBackend.sln]
SUBGRAPH_REPO --> SUBMODULE
SUBMODULE --> BASE_SRC[Base Source Code<br/>(Host, Base.Domain)]
SUBMODULE --> BASE_TESTS[Base Testing Infrastructure<br/>(Base.Testing.Infrastructure)]
SPECIALIZED_SRC -->|References| BASE_SRC
SPECIALIZED_TESTS -->|References| BASE_TESTS
SOLUTION_FILE --> BASE_SRC
SOLUTION_FILE --> SPECIALIZED_SRC
SOLUTION_FILE --> BASE_TESTS
SOLUTION_FILE --> SPECIALIZED_TESTS
Generation-Time Extension (Factory Composition)¶
- Mechanism: Overlays are applied sequentially to a base template artifact.
- Overlay Application: The Factory's template generator merges code, documentation, and metadata from overlays into a flattened, final template.
- Token Replacement: Placeholders (e.g.,
{{ServiceName}},{{RootNamespace}}) are replaced with user-provided values. - File Merging: New files are added, existing files are patched (e.g.,
Program.csmodifications), and content is inserted between markers. - Documentation Merging: Base documentation and overlay-specific documentation are combined.
Reference Wiring Mechanisms¶
This section details how different components of the template system are connected and how extensibility is achieved.
How Base Test Infrastructure References Specialized Services¶
ITestAppFactory: The base testing infrastructure defines an interface likeITestAppFactory(e.g., inBase.Testing.Infrastructure).- Specialized Implementations: Specialized templates provide concrete implementations (e.g.,
IdentityTestAppFactoryinIdentity.AcceptanceTests) that configure aWebApplicationFactory<TProgram>for their specific service. - Abstract Base Tests: Base test classes (e.g.,
AcceptanceTestBase) use this factory to createHttpClientinstances and accessIServiceProvider, allowing domain-specific tests to reuse common test patterns.
How Base Documentation References Specialized Documentation¶
- Build Time: Specialized template
mkdocs.ymlcan include base documentation files via relative paths to the submodule. - Generation Time: The template generator merges documentation files from the base and overlays into the final documentation site structure. Cross-links are maintained and updated during this process.
How Base Metrics/Options Infrastructure Discovers Specialized Implementations¶
- Extension Point Interfaces: Base libraries define interfaces like
IMetricsFeatureandIConfigureOptions<T>. - DI Scanning: The base host's
Program.cs(or a dedicated extension method) uses dependency injection (DI) container scanning (e.g.,services.Scan().FromApplicationDependencies().AddClasses().AsImplementedInterfaces()) to automatically discover and register all implementations of these interfaces from loaded assemblies (including specialized domain projects). - Runtime Registration: This allows specialized templates to "plug in" their domain-specific metrics and options configurations without the base having any explicit knowledge or references to them.
graph TD
BASE_HOST[Base Host Application<br/>(Program.cs)]
BASE_DI[Base DI Container<br/>(services.Scan)]
BASE_METRICS_INFRA[ConnectSoft.Extensions.Metrics<br/>(IMetricsFeature)]
BASE_OPTIONS_INFRA[ConnectSoft.Extensions.Options<br/>(IConfigureOptions<T>)]
IDENTITY_METRICS[Identity.Infrastructure<br/>(IdentityMetricsFeature)]
IDENTITY_OPTIONS[Identity.Infrastructure<br/>(ConfigureIdentitySecurityOptions)]
IDENTITY_TEST_FACTORY[Identity.AcceptanceTests<br/>(IdentityTestAppFactory)]
BASE_HOST --> BASE_DI
BASE_DI -->|Discovers & Registers| IDENTITY_METRICS
BASE_DI -->|Discovers & Registers| IDENTITY_OPTIONS
BASE_METRICS_INFRA -->|Defines Interface| IDENTITY_METRICS
BASE_OPTIONS_INFRA -->|Defines Interface| IDENTITY_OPTIONS
BASE_TEST_INFRA[Base.Testing.Infrastructure<br/>(ITestAppFactory, AcceptanceTestBase)]
BASE_TEST_INFRA -->|Defines Interface & Base Class| IDENTITY_TEST_FACTORY
Related Documents¶
- Template Layering and Reuse - Three-layer architecture guide
- Template Metadata Composition - Template.json composition details
- Template Overlays Specification - Overlay system and versioning
- Metrics, Options and Testing Extensibility - Extension point patterns