Building a Solution with dotnet cli templates
2017-02-20
In a previous post I showed an example of using dotnet cli commands to create a sample web solution with a web project that has dependencies on models and services projects and a test project that also is in the mix. I personally think that is super useful and I can think of scenarios where I will be using that. Another scenario is where you have a project starting and you already know how you want your project setup.
Let's take the previous post's setup and the starting point for the template feature in the new dotnet cli. The structure for that project was as follows:
- SampleApp
- Models/
- Services/
- Services.Test/
- Web/
SampleApp.sln
It would be nice to be able to have a simple command handy for the team or a project bootstrapper to get thing started. The team behind the dotnet cli made this pretty easy by just adding an additional .template.config
directory and a template.json
file within that directory you can have a template sitting on the file system that allows you do create an entire project structure in one shot.
- mytemplate
- .template.config/
- template.json
- Models/
- Services/
- Services.Test/
- Web/
mytemplate.sln
In this example my template.json
file has the following
{
"author": "Some Author",
"classifications": ["mytemplate"],
"name": "mytemplate",
"identity": "mytemplate",
"shortName": "mytemplate",
"tags": {
"language": "C#",
"type": "solution"
},
"sourceName": "mytemplate"
}
sourceName
attribute. For my simple example when the template is initiated and your project is created it will use the supplied --name
value to, in this case, name the solution file your supplied value.
For example, dotnet new mytemplate -all --name sampleapp --output sampleapp-location
would create a solution called sampleapp.sln
based on the name value and drop it into a directory called sampleapp-location
After you have the file system based template created in a well-known location you need to tell the dotnet cli about it by installing it with dotnet new -i path/to/your/template/root
. Make sure it was installed correctly by calling the list command with and you should see your template along side the shipping templates with dotnet new --list -all
.
Templates Short Name Language Tags
---------------------------------------------------------------------------
Console Application console [C#], F# Common/Console
Class library classlib [C#], F# Common/Library
Unit Test Project mstest [C#], F# Test/MSTest
xUnit Test Project xunit [C#], F# Test/xUnit
Empty ASP.NET Core Web Application web [C#] Web/Empty
MVC ASP.NET Core Web Application mvc [C#], F# Web/MVC
Web API ASP.NET Core Web Application webapi [C#] Web/WebAPI
mytemplate mytemplate [C#] mytemplate
Nuget Config nugetconfig Config
Web Config webconfig Config
Solution File sln Solution
I wrapped some of this up in a variation of the previous script.
Param(
[string] [Parameter(Mandatory=$true)] $SolutionName,
[ValidateSet('netcoreapp1.0','netcoreapp1.1')]
[string] $framework = "netcoreapp1.1"
)
# Create source directory and change directory to it
New-Item -ItemType Directory -Path $SolutionName | Out-Null
# Set some defaults names & paths
$webProject = "Web"
$modelsProject = "Models"
$servicesProject = "Services"
$servicesTestProject = "$servicesProject.Tests"
$webProjectPath = "$webProject\$webProject.csproj"
$modelsProjectPath = "$modelsProject\$modelsProject.csproj"
$servicesProjectPath = "$servicesProject\$servicesProject.csproj"
$servicesTestProjectPath = "$servicesTestProject\$servicesTestProject.csproj"
#Create all of our individual projects
dotnet new mvc --name $webProject --output $SolutionName\$webProject --framework $framework
dotnet new classlib --name $modelsProject --output $SolutionName\$modelsProject --framework $framework
dotnet new classlib --name $servicesProject --output $SolutionName\$servicesProject --framework $framework
dotnet new xunit --name $servicesTestProject --output $SolutionName\$servicesTestProject --framework $framework
#Add all of our individual projects to the solution
dotnet new sln --name $SolutionName --output $SolutionName
$solutionPath = ".\$solutionName\$SolutionName.sln"
dotnet sln $solutionPath add .\$SolutionName\$webProjectPath
dotnet sln $solutionPath add .\$SolutionName\$modelsProjectPath
dotnet sln $solutionPath add .\$SolutionName\$servicesProjectPath
dotnet sln $solutionPath add .\$SolutionName\$servicesTestProjectPath
# Add all the of the nessessary project references
dotnet add .\$SolutionName\$webProjectPath reference .\$SolutionName\$modelsProjectPath
dotnet add .\$SolutionName\$webProjectPath reference .\$SolutionName\$servicesProjectPath
dotnet add .\$SolutionName\$servicesProjectPath reference .\$SolutionName\$modelsProjectPath
dotnet add .\$SolutionName\$servicesTestProjectPath reference .\$SolutionName\$modelsProjectPath
dotnet add .\$SolutionName\$servicesTestProjectPath reference .\$SolutionName\$servicesProjectPath
New-Item -ItemType Directory -Path "$SolutionName\.template.config" | Out-Null
@"
{
"author": "Some Author",
"classifications": ["$SolutionName"],
"name": "$SolutionName",
"identity": "$SolutionName",
"shortName": "$SolutionName",
"tags": {
"language": "C#",
"type": "solution"
},
"sourceName": "$SolutionName"
}
"@ | Out-File -FilePath "$SolutionName\.template.config\template.json" -Encoding ascii
dotnet new -i .\$SolutionName
dotnet new --list -all