Skip to content

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 structure
  • saif-feature-api - API layer
  • saif-feature-database-cosmosdb - Azure Cosmos DB integration
  • saif-feature-database-oracle - Oracle Database integration
  • saif-feature-front-end-react - React UI framework
  • saif-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 packages
  • saif-terraform-module - Infrastructure as Code modules
  • saif-typespec-package - OpenAPI specifications
  • saif-test-tools - Testing utilities
  • saif-dynatrace-config - Monitoring configuration
  • saif-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 selection
  • shared.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 name
  • shared.application_name.template.json - Application naming parameters
  • shared.api_type.g.template.json - API classification
  • shared.project_id.template.json - Project identifier
  • shared.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 / #endif blocks
  • TypeSpec (.tsp): //#if / //#else / //#elif / //#endif blocks
  • Markdown (.md): ---#if / ---#else / ---#elif / ---#endif blocks

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:

  1. Make setup scripts executable on non-Windows platforms
  2. Run scripts/setup.ps1 with all symbol values substituted
  3. The setup script orchestrates generation of feature templates based on user choices

Example flow when creating an Experience API with React and Cosmos DB:

dotnet new saif-api-exp `
  --name MyApp `
  --database_type cosmosdb `
  --front_end_type React

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:

  1. Add new parameters

  2. Edit shared symbol files for reusable parameters

  3. Or add to template.json symbols section for template-specific parameters

  4. Add new files or structure

  5. Place files in the template directory

  6. Use sources.modifiers.rename for hidden files (.gitignore, .editorconfig, etc.)

  7. Add conditional logic

  8. Use appropriate syntax based on file type (PowerShell, TypeSpec, or Markdown)

  9. Example in PowerShell:

    #if (is_external_app == true)
    # External-facing code
    #endif
    

  10. Update setup scripts

  11. Modify scripts/setup.ps1 to invoke new feature templates

  12. Pass parameters using placeholder names like ApplicationName1, DatabaseType1

  13. Test thoroughly

  14. Install the template from source and generate output (see Validating Template Changes Locally)
  15. 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 --name parameter)
  • BusinessDomain1 → Your business domain (from --business_domain parameter)
  • Owner1 → Your team name (from --owner parameter)
  • ProjectId1 → Your project identifier (from --project_id parameter)
  • DatabaseType1 → Selected database type (from --database_type parameter: oracle, cosmosdb, none)
  • FrontEndType1 → Selected UI framework (from --front_end_type parameter: 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 dotnet CLI)
  • Docker Desktop
  • Visual Studio (recommended)

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:

dotnet new list saif-

Creating and Using Templates

Setup: Configure NuGet Source

Check that the SAIFCorporation package source is configured:

dotnet nuget list source

If not present, add it:

dotnet nuget add source https://pkgs.dev.azure.com/SAIFCorporation/_packaging/SAIFCorporation/nuget/v3/index.json -n SAIFCorporation

Install Production Templates

Install the production templates package:

dotnet new install SAIF.Platform.Templates

Using dotnet new

Once templates are installed, create a new project using the dotnet new CLI:

dotnet new saif-api-sys --name MyApi --business_domain IT --owner Architecture --force

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:

dotnet new saif-api-sys --help

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-publish optional 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 new for 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.

Validating Template Changes Locally

When you modify templates, validate them by installing from source and generating output:

# Install the modified template from source
dotnet new install src/templates/saif-api-exp --force

# Generate into a scratch directory and inspect the output
$testDir = "$env:TEMP/template-test-$(Get-Random)"
New-Item -ItemType Directory -Path $testDir
Push-Location $testDir
dotnet new saif-api-exp --name TestApp --business_domain pol --owner Architecture --allow-scripts no
Get-ChildItem -Recurse -Name
Pop-Location; Remove-Item $testDir -Recurse -Force

Template configuration parsing is covered by unit tests:

dotnet test src/dotnet/tests/SAIF.Platform.CLI.UnitTests --filter FullyQualifiedName~Templates

Using Templates

Verify SAIFCorporation Source

Check that the SAIFCorporation package source is configured:

dotnet nuget list source

If not present, add it:

dotnet nuget add source https://pkgs.dev.azure.com/SAIFCorporation/_packaging/SAIFCorporation/nuget/v3/index.json -n SAIFCorporation

Install Templates

Install the production templates package:

dotnet new install SAIF.Platform.Templates

Next Steps