Creating dotnet solution and project templates

This article should how to create and deploy dotnet templates which can be used from the dotnet CLI or from Visual Studio.

Code: https://github.com/damienbod/Blazor.BFF.OpenIDConnect.Template

Folder Structure

The template folder structure is important when creating dotnet templates. The .template.config must be created inside the content folder. This folder has a template.json file and an icon.png image which is displayed inside Visual Studio once installed. The json structure of the template.json has then a few required objects and properties. You can create different type of templates.

The Blazor.BFF.OpenIDConnect.Template project is an example of a template I created for a Blazor ASP.NET Core solution with three projects and implements the backend for frontend security architecture using OpenID Connect.

{
    "author": "damienbod",
    "classifications": [
        "AspNetCore",
        "WASM",
        "OpenIDConnect",
		"OAuth2",
		"Web",
		"Cloud",
		"Console",
		"Solution",
		"Blazor"
    ],
    "name": "ASP.NET Core Blazor BFF hosted WASM OpenID Connect",
    "identity": "Blazor.BFF.OpenIDConnect.Template",
    "shortName": "blazorbffoidc",
    "tags": {
        "language": "C#",
        "type":"solution"
    },
    "sourceName": "BlazorBffOpenIDConnect",
    "preferNameDirectory": "true",
    "guids": [
		"CFDA20EC-841D-4A9C-A95C-2C674DA96F23",
		"74A2A84B-C3B8-499F-80ED-093854CABDEA",
		"BD70F728-398A-4A88-A7C7-A3D9B78B5AE6"
    ],
	"symbols": {
		"HttpsPortGenerated": {
		  "type": "generated",
		  "generator": "port",
		  "parameters": {
			"low": 44300,
			"high": 44399
		  }
		},
		"HttpsPortReplacer": {
		  "type": "generated",
		  "generator": "coalesce",
		  "parameters": {
			"sourceVariableName": "HttpsPort",
			"fallbackVariableName": "HttpsPortGenerated"
		  },
		  "replaces": "44348"
		}
   }
}

The tags property

The tags object must be set correctly for Visual Studio to display the template. The type property must be set to solution, project or item. The type property must be set with a correct value otherwise it will not be visible inside Visual Studio even though the template will still install in the CLI and run from the CLI.

"tags": {
  "language": "C#",
  "type":"solution" // project, item
},

HTTP Ports

I like to update the HTTP ports when creating a new solution or project from the template. I do not want to add a parameter for the HTTP port because the user will be required to add a value in Visual Studio. If the user enters nothing, the template will create nothing without an error. Anywhere the port 44348 is found in a launchSettings.json file, this will be updated with a new value inside the range. This will only work if the port number exists already in the template. This must match your content!

"symbols": {
	"HttpsPortGenerated": {
	  "type": "generated",
	  "generator": "port",
	  "parameters": {
		"low": 44300,
		"high": 44399
	  }
	},
	"HttpsPortReplacer": {
	  "type": "generated",
	  "generator": "coalesce",
	  "parameters": {
		"sourceVariableName": "HttpsPort",
		"fallbackVariableName": "HttpsPortGenerated"
	  },
	  "replaces": "44348"
	}
}

Solution GUIDs

The GUIDs are used to replace the existing solution GUIDs from the solution file with new random GUIDs when creating a new solution using the template. The GUIDs must exist in your solution file, otherwise there is nothing to replace.

"guids": [
   "CFDA20EC-841D-4A9C-A95C-2C674DA96F23",
   "74A2A84B-C3B8-499F-80ED-093854CABDEA",
   "BD70F728-398A-4A88-A7C7-A3D9B78B5AE6"
],

Namespaces, sourceName, project names

The sourceName value is used to replace this value with the new name value passed as the -n parameter or the project name inside Visual Studio. The value of the property is used and everywhere in the content, the projects and the namespaces are replaced with the passed parameter. It is important that when you create the content for the template, the namespaces and the projects use the same value as the sourceName value.

classifications

The classifications value is important when using inside Visual Studio. You can use this to filter and find your template in the “create new solution/project” UI.

Create a template Nuget package

I deploy the template as a Nuget package. I use a nuspec file for this. This can be used to create a nupkg file which can be uploaded to Nuget. You could also create a package from a dotnet project file.

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
	<metadata>
		<id>Blazor.BFF.OpenIDConnect.Template</id>
		<version>1.2.6</version>
		<title>Blazor.BFF.OpenIDConnect.Template</title>
		<license type="file">LICENSE</license>
		<description>Blazor backend for frontend (BFF) template for WASM ASP.NET Core hosted</description>
			<projectUrl>https://github.com/damienbod/Blazor.BFF.OpenIDConnect.Template</projectUrl>
		<authors>damienbod</authors>
		<owners>damienbod</owners>
		<icon>./BlazorBffOpenIDConnect/.template.config/icon.png</icon>
		<language>en-US</language>
		<tags>Blazor BFF WASM ASP.NET Core</tags>
		<requireLicenseAcceptance>false</requireLicenseAcceptance>
		<copyright>2022 damienbod</copyright>
		<summary>This template provides a simple Blazor template with BFF server authentication WASM hosted</summary>
		<releaseNotes>Improved template with http port generator, update packages</releaseNotes>
		<repository type="git" url="https://github.com/damienbod/Blazor.BFF.OpenIDConnect.Template" />
		<packageTypes>
			<packageType name="Template" />
		</packageTypes>
	</metadata>
</package>

Installing

The template can be installed using the dotnet CLI. The name of the template is defined in the template file. The dotnet CLI run can be used to create a new solution or project depending on your template type. The -n is used to define the name of the projects and the namespaces.

// install
dotnet new -i Blazor.BFF.OpenIDConnect.Template

// run
dotnet new blazorbffoidc -n YourCompany.Bff

Visual Studio

After installing using the dotnet CLI, the template will be visible inside Visual Studio, if the tags type is set correctly. The icon will be displayed if the correct icon.png is added to the .template.config folder.

Notes

Creating and using templates using the dotnet CLI is really powerful and very simple to use. There are a few restrictions which must be followed and the docs are a bit light. This github repo is a great starting point and is where I would go to learn and create your first template. If deploying the template to Visual Studio and using in the dotnet CLI, you need to test both. Entering HTTP port parameters does not work so good in Visual Studio as no default value is set if the user does not enter this. I was not able to get the VSIX extensions to work within a decent time limit but will probably come back to this at some stage. I had many problems with the target type and XML errors when deploying and so on. The dotnet CLI works great and can be used anywhere and the templates can be used in Visual Studio as well, this is enough for me. I think the dotnet CLI templates feature is great and makes it really used to get started faster when creating software solutions.

Links:

https://github.com/sayedihashimi/template-sample

https://www.nuget.org/packages/Blazor.BFF.OpenIDConnect.Template/

https://dotnetnew.azurewebsites.net/

https://devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/

https://docs.microsoft.com/en-us/dotnet/core/tools/custom-templates

https://github.com/dotnet/aspnetcore/tree/main/src/ProjectTemplates

https://json.schemastore.org/template

https://docs.microsoft.com/en-us/dotnet/core/tutorials/cli-templates-create-item-template

5 comments

  1. […] Creating dotnet solution and project templates (Damien Bowden) […]

  2. Hi Damien – Template Engine PM here 🙂 Sayed’s repo is a great resource for sure.

    Did you ever use the in-repo documentation at dotnet/templating? Did you find concepts or examples missing from it? It might help us identify gaps and fill them if you had some specific pointers.

    Anyway, glad you found them useful – the templates look great!

    1. HI chusk3

      Thanks for reaching out and thanks. I am missing a doc for creating custom templates. I found pieces in different places and and maybe some sub topics in this doc would help?

      https://docs.microsoft.com/en-us/dotnet/core/tools/custom-templates

      – Common settings in the json file
      1. Namespaces
      2. Guids
      3. Tags
      4. Icon
      5. Visual Studio specifics
      6. shortName
      7. identity
      8. classifications
      9. preferNameDirectory
      10. …
      – Create a custom template for an ASP.NET Core Web application (solution/project)
      1. HTTP ports
      2. Target version
      3. Initial app.settings
      – Create a custom template for a desktop application
      1. App.config
      2. …
      – Deploying templales to nuget

      I have not really thought this through, but at least a doc about the common settings and how these effect the resulting solution, project or item that is created.

      Greetings Damien

  3. […] Creating dotnet solution and project templates […]

  4. […] Creating dotnet solution and project templates – Damien Bowden […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: