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. Run tests with dotnet test
  15. Use DiffEngineTray to review snapshot changes
  16. 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)
  • 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:

dotnet new list saif-

Creating and Using Templates

Setup: Configure NuGet Source

Check that the SAIFNuget package source is configured:

dotnet nuget list source

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:

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.

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:

dotnet tool install -g DiffEngineTray

Launch it:

diffenginetray

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

cd src/dotnet/tests/SAIF.Platform.Templates.UnitTests
dotnet test

Review and Accept Changes

  1. Click the DiffEngineTray icon in your system tray to view diffs
  2. Accept or reject each diff as needed
  3. If accepting changes, run the test command to accept pending snapshot changes:
dotnet verify accept -y
  1. Re-run tests to confirm they pass:
dotnet test

Using Templates

Verify SAIFNuget Source

Check that the SAIFNuget package source is configured:

dotnet nuget list source

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:

dotnet new install SAIF.Platform.Templates

Next Steps