SAIF DotNet CLI Project Templates¶
👷 For Platform Contributors: This guide is for developers working on the Forge template system. For using templates to create applications, see Creating and Using Templates.
SAIF provides a collection of dotnet new templates for creating standardized projects. These templates are packaged and distributed via NuGet, making it easy to bootstrap new applications with consistent structure and configuration.
📋 Overview¶
| Aspect | Details |
|---|---|
| Location | src/templates/ |
| Configuration | JSON files in .template.config/ directories |
| Distribution | NuGet package (SAIF.Platform.Templates) |
| Interfaces | dotnet new CLI or SAIF CLI |
| Target Audience | Platform contributors and app developers |
📚 Reference¶
📖 See Microsoft Documentation for template authoring details.
Template Structure Overview¶
Templates in src/templates/ use JSON configuration files following the Microsoft dotnet new template schema. Each template is self-contained with its own configuration and can inherit shared symbol definitions from the shared/ subdirectory.
Working with Template Files¶
All templates are located in src/templates/. Each template is a self-contained directory that follows the dotnet new template convention. Templates are organized into three categories:
Template Categories¶
1. Main API Templates¶
These generate complete application solutions with .NET projects, infrastructure, and CI/CD:
saif-api-sys- System API (integrates with backend systems or data sources)saif-api-exp- Experience API (user-facing, aggregates multiple APIs)saif-api-proc- Process API (business process orchestration)
Each inherits shared configuration and automatically generates feature templates via post-actions.
2. Feature Templates¶
These add functionality to existing applications without duplicating core structure:
saif-feature-base- Core application structuresaif-feature-api- API layersaif-feature-database-cosmosdb- Azure Cosmos DB integrationsaif-feature-database-oracle- Oracle Database integrationsaif-feature-front-end-react- React UI frameworksaif-feature-event-subscription- Event-driven capabilities
Feature templates are called by main API template setup scripts with symbol values automatically substituted.
3. Package Templates¶
Specialized templates for reusable libraries and infrastructure:
saif-nuget-package- .NET NuGet packagessaif-terraform-module- Infrastructure as Code modulessaif-typespec-package- OpenAPI specificationssaif-test-tools- Testing utilitiessaif-dynatrace-config- Monitoring configurationsaif-azure-terraform-team- Team infrastructure- And others...
Template File Structure¶
Each template contains a .template.config/ directory with JSON configuration files:
template.json (required)
- Main template metadata and configuration
- Defines template identity, name, and short name (the name used with
dotnet new) - Lists shared configuration files to include via
additionalConfigFiles - Defines symbol parameters and their properties
- Configures post-actions (scripts to run after generation)
- Maps source names for file/folder renaming (e.g.,
SAIF.App1→ your project name)
Example structure:
{
"$schema": "http://json.schemastore.org/template",
"identity": "SAIF.Service.Api.System",
"name": "SAIF Service - System Api",
"shortName": "saif-api-sys",
"sourceName": "SAIF.App1",
"additionalConfigFiles": [
"shared.api_type.g.template.json",
"shared.database_type.template.json",
"shared.custom_operations.template.json"
],
"symbols": {
"skip_setup": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false"
}
},
"postActions": []
}
Shared Symbol Files (shared.*.template.json)
Reusable symbol definitions shared across multiple templates. Located in the shared/ subdirectory:
shared.business_domain.template.json- Business domain selectionshared.database_type.g.template.json- Database type choice (Oracle, Cosmos, None)shared.front_end_type.template.json- UI framework (None, React)shared.owner.template.json- Owning team nameshared.application_name.template.json- Application naming parametersshared.api_type.g.template.json- API classificationshared.project_id.template.json- Project identifiershared.cli_runner.template.json- CLI execution configuration
shared.custom_operations.template.json
Configures conditional syntax processing for different file types. This allows templates to include/exclude code based on symbol values:
- PowerShell (
.ps1):#if/#else/#elif/#endifblocks - TypeSpec (
.tsp)://#if///#else///#elif///#endifblocks - Markdown (
.md):---#if/---#else/---#elif/---#endifblocks
Example in PowerShell:
#if (database_type == "oracle")
& $cli new saif-feature-database-oracle $databaseArgs.Split(' ') $allowScripts.Split(' ') $extraArgs.Split(' ')
#elseif (database_type == "cosmosdb")
& $cli new saif-feature-database-cosmosdb $databaseArgs.Split(' ') $allowScripts.Split(' ') $extraArgs.Split(' ')
#endif
Post-Actions and Setup Scripts¶
Main API templates include post-actions that:
- Make setup scripts executable on non-Windows platforms
- Run
scripts/setup.ps1with all symbol values substituted - The setup script orchestrates generation of feature templates based on user choices
Example flow when creating an Experience API with React and Cosmos DB:
The post-action calls scripts/setup.ps1 which generates:
saif-feature-base(core structure)saif-feature-api(API layer)saif-feature-front-end-react(React UI)saif-feature-database-cosmosdb(Cosmos DB integration)
All with parameters automatically substituted.
Modifying Templates¶
When adding or changing template functionality:
-
Add new parameters
-
Edit shared symbol files for reusable parameters
-
Or add to
template.jsonsymbols section for template-specific parameters -
Add new files or structure
-
Place files in the template directory
-
Use
sources.modifiers.renamefor hidden files (.gitignore,.editorconfig, etc.) -
Add conditional logic
-
Use appropriate syntax based on file type (PowerShell, TypeSpec, or Markdown)
-
Example in PowerShell:
-
Update setup scripts
-
Modify
scripts/setup.ps1to invoke new feature templates -
Pass parameters using placeholder names like
ApplicationName1,DatabaseType1 -
Test thoroughly
- Run tests with
dotnet test - Use DiffEngineTray to review snapshot changes
- Test multiple symbol combinations
Symbol Replacement¶
Symbols use placeholder patterns in template files that get replaced with actual values during generation. Common placeholders:
ApplicationName1→ Your actual project name (from--nameparameter)BusinessDomain1→ Your business domain (from--business_domainparameter)Owner1→ Your team name (from--ownerparameter)ProjectId1→ Your project identifier (from--project_idparameter)DatabaseType1→ Selected database type (from--database_typeparameter: oracle, cosmosdb, none)FrontEndType1→ Selected UI framework (from--front_end_typeparameter: None, React)
Setup scripts receive these values with symbols already replaced, enabling feature templates to inherit parameters from main templates. For example, when the post-action runs scripts/setup.ps1, all ApplicationName1 references are already replaced with your actual project name.
Development Prerequisites¶
- .NET SDK (includes
dotnetCLI) - Docker Desktop
- Visual Studio (recommended)
- DiffEngineTray (for test result comparison when modifying templates)
Building Templates Locally¶
Install Templates from Source¶
To build and install templates for local development:
cd src/dotnet/SAIF.Platform.Templates
dotnet build --configuration Release
dotnet pack --no-build --configuration Release --output ./bin
dotnet new uninstall SAIF.Platform.Templates
dotnet new install ./bin/SAIF.Platform.Templates.1.0.0.nupkg
Verify Installation¶
List all installed SAIF templates:
Creating and Using Templates¶
Setup: Configure NuGet Source¶
Check that the SAIFNuget package source is configured:
If not present, add it:
dotnet nuget add source https://tfs.saif.com/SAIFCodeCollection/_packaging/SAIFNuget/nuget/v3/index.json -n SAIFNuget
Install Production Templates¶
Install the production templates package:
Using dotnet new¶
Once templates are installed, create a new project using the dotnet new CLI:
Example: Experience API with Cosmos DB¶
dotnet new saif-api-exp `
--name MyExperienceApp `
--business_domain pol `
--owner Architecture `
--front_end_type None `
--is_external_app false `
--database_type cosmosdb `
--cosmos_api_type nosql `
--allow-scripts yes
View Template Options¶
See all available parameters for a template:
Post-Generation¶
After generation:
- Open the solution in Visual Studio
- Press F5 to start the application and view it in the browser
- The Aspire dashboard will display your running services (API, Cosmos DB, etc.)
Using SAIF CLI¶
The SAIF CLI provides a streamlined interface for working with templates, offering non-interactive and enhanced workflows:
saif new saif-api-exp `
--name MyExperienceApp `
--business_domain pol `
--owner Architecture `
--front_end_type React `
--database_type cosmosdb
Key differences when using the SAIF CLI:
- Non-interactive: Templates generate automatically without prompts (
--no-interactive) - Automatic publishing: Generated projects are ready to publish (
--no-publishoptional to skip) - Batch generation: Feature templates are chained together seamlessly
- Simplified parameters: SAIF CLI handles parameter validation and defaults
The SAIF CLI ultimately invokes these templates behind the scenes, so both approaches use the same underlying template system. Choose based on your workflow preferences:
- Use
dotnet newfor interactive exploration and custom configurations - Use SAIF CLI for automated, production-ready generation with sensible defaults
Template Structure Overview¶
Templates in src/templates/ use JSON configuration files following the Microsoft dotnet new template schema. Each template is self-contained with its own configuration and can inherit shared symbol definitions from the shared/ subdirectory.
Running Tests Locally¶
When you modify templates, update the corresponding tests to account for your changes.
Setup DiffEngineTray¶
DiffEngineTray monitors pending snapshot changes and provides a visual interface for accepting them.
Install the tool:
Launch it:
The tool runs in your Windows system tray. When tests produce snapshot differences, DiffEngineTray displays them grouped by solution and provides options to:
- Accept all - Accept all pending changes
- Discard - Clear all tracked items
- Accept individual diffs - Review and accept specific changes
- View diffs - Open changes in your configured diff tool
- Purge verified files - Clean up old snapshot files
For more details, see the DiffEngineTray documentation.
Run Tests¶
Review and Accept Changes¶
- Click the DiffEngineTray icon in your system tray to view diffs
- Accept or reject each diff as needed
- If accepting changes, run the test command to accept pending snapshot changes:
- Re-run tests to confirm they pass:
Using Templates¶
Verify SAIFNuget Source¶
Check that the SAIFNuget package source is configured:
If not present, add it:
dotnet nuget add source https://tfs.saif.com/SAIFCodeCollection/_packaging/SAIFNuget/nuget/v3/index.json -n SAIFNuget
Install Templates¶
Install the production templates package:
Next Steps¶
- Create a new project: See Creating and Using Templates
- Run the generated app: See Post-Generation
- Contribute to templates: See Modifying Templates
- Learn about Forge: See About Forge