Skip to content

Latest commit

 

History

History
65 lines (40 loc) · 4.55 KB

File metadata and controls

65 lines (40 loc) · 4.55 KB

Development Guide

This document explains how the Avalonia dotnet new templates are structured, how to build and test them locally, and how to add new templates or parameters. If you only want to use the templates, see the README.md instead.

This guide covers the Avalonia-specific conventions. For a step-by-step walkthrough, see the dotnet template tutorial; for the full template.json schema and options, see the .NET custom templates reference and the dotnet/templating samples.

How the templates work

Everything ships as a single NuGet package, Avalonia.Templates, defined by Avalonia.Templates.csproj. The .csproj doesn't compile any code, it only packs everything under templates/ into the package.

Each template lives in its own folder under templates/ and is described by a .template.config/ directory:

File Purpose
template.json The template definition, including parameters (symbols).
dotnetcli.host.json Maps parameters to their CLI arguments.
ide.host.json Maps parameters to their IDE settings.

C# and F# variants are kept as separate templates under templates/csharp/ and templates/fsharp/, but share the same short name (e.g. avalonia.app) and are told apart by their language tag.

Building and installing locally

To try your changes, pack the templates and install them from the local package:

./install-dev-templates.ps1

This uninstalls any existing Avalonia.Templates, runs dotnet pack, and installs the freshly built .nupkg.

Testing

Templates are tested by generating projects from them and building the results. The test script is tests/build-test.ps1. Run it from the tests folder:

cd tests
./build-test.ps1

It creates every application template with different combinations of parameters and builds each one, in parallel, to make sure it compiles. Each build writes its own binary log to binlog/; pass -ThrottleLimit <n> to change how many builds run at once (it defaults to the CPU count).

Pass -NuGetSource <url> to restore from an extra feed, e.g. to test the templates against an Avalonia nightly build.

The build matrix is data-driven: every variant is a New-Case row in the $builds array, and the item templates instantiated into the MVVM projects are New-ItemCase rows in $itemTemplates. When you add a new template or parameter, add a matching New-Case row so it gets built in CI.

Adding a new template

Add a new template under templates/csharp/<your-template>/ (and templates/fsharp/... for an F# variant), with a unique identity and shortName in template.json, and update the CLI/IDE files if it takes parameters (see below). The existing templates are the best reference.

The C# and F# variants share a shortName and groupidentity, but each identity must be unique — a duplicate makes the engine register only one, so dotnet new <name> -lang C# fails with "Allowed values for '-lang' option are: 'F#'". Convention: suffix the F# identity with .FSharp.

Finally, add build coverage with a New-Case row in tests/build-test.ps1 and document it in README.md.

Adding a new parameter

A parameter is a symbol in template.json, given a CLI name in dotnetcli.host.json and an IDE label in ide.host.json. Make sure to update all three files. Without the CLI and IDE entries, the parameter won't be usable from the command line or shown in IDEs.

Mirror the parameter across the C# and F# variants — don't expose an option a language doesn't actually implement, or it becomes a silent no-op (F# xplat once declared MainViewPageType while its MainView ignored it). Removing a parameter also means deleting its computed symbols and sources[].modifiers conditions, not just the three host files; grep the template folder for the symbol name first.

Add test coverage with a New-Case row in tests/build-test.ps1 for each value of a choice/bool parameter, not just the default — #if branches only compile when the value is selected, so a broken non-default branch passes CI until something builds it. Document the parameter in README.md.