.NET Core solution management via the command line interface
Posted on Monday, 3rd July 2017
One of the strengths boasted by .NET Core is its new command line interface (CLI for short), and by now you’re probably aware that Visual Studio, Rider, Visual Studio Code etc shell out to the .NET Core CLI under the bonnet for most .NET Core related operations, so it makes sense that what you’re able to do in your favourite IDE you’re also able to do via the CLI.
With this in mind, only recently did I spend the time and effort to investigate how easy it was to create and manage a project solution via the CLI, including creating the solution structure, referencing projects along the way and adding them to .NET’s .sln file.
It turns out it’s incredibly easy and has instantly become my preferred way of managing solutions. Hopefully by the end of this post you’ll arrive at the same conclusion too.
Benefits of using the CLI for solution management
So what are the benefits of using the CLI for solution management? Let’s have a look:
Something that has always been a fiddly endevour of UI interactions is now so much simpler via the CLI - what’s more, you don’t need to open your editor of choice if you want to create references or update a NuGet package.
Using the CLI for creating projects and solutions is particularly helpful if (like me) you work across multiple operating systems and want to normalise your tool chain.
Loading an IDE just to update a NuGet package seems unnecessary
Let’s begin!
Creating our solution
So let’s take a look at how we can create the following project structure using the .NET Core CLI.
piedpiper
└── src
├── piedpiper.domain
├── piedpiper.sln
├── piedpiper.tests
└── piedpiper.website
First we’ll create our solution (.sln) file, I’ve always preferred to create the solution file in the top level source folder but the choice is yours (just bear in mind to specify the right path in the commands used throughout the rest of this post).
# /src/
$ dotnet new sln -n piedpiper
This will create a new sln
file called piedpiper.sln
.
Next we use the output parameter on the dotnet new <projecttype>
command to create a project in a particular folder:
# /src/
$ dotnet new mvc -o piedpiper.website
This will create an ASP.NET Core MVC application in the piedpiper.website folder in the same directory. If we were to look at our folder structure thus far it looks like this:
# /src/
$ ls -la
piedpiper.sln
piedpiper.website
Next we can do the same for our domain and test projects:
# /src/
$ dotnet new classlib -o piedpiper.domain
$ dotnet new xunit -o piedpiper.tests
Adding our projects to our solution
At this point we’ve got a solution file that has no projects referenced, we can verify this by calling the list
command like so:
# /src/
$ dotnet sln list
No projects found in the solution.
Next we’ll add our projects to our solution file. Once upon a time doing this involved opening Visual Studio then adding a reference to each project manually. Thankfully this can also be done via the .NET Core CLI.
Now start to add each project with the following command, we do this by referencing the .csproj file:
# /src/
$ dotnet sln add piedpiper.website/piedpiper.website.csproj
$ dotnet sln add piedpiper.domain/piedpiper.domain.csproj
$ dotnet sln add piedpiper.tests/piedpiper.tests.csproj
Note: If you’re using a Linux/Unix based shell you can do this in a single command using a globbing pattern!
# /src/
$ dotnet sln add **/*.csproj
Project `piedpiper.domain/piedpiper.domain.csproj` added to the solution.
Project `piedpiper.tests/piedpiper.tests.csproj` added to the solution.
Project `piedpiper.website/piedpiper.website.csproj` added to the solution.
Now when we call list
on our solution file we should get the following output:
# /src/
$ dotnet sln list
Project reference(s)
--------------------
piedpiper.domain/piedpiper.domain.csproj
piedpiper.tests/piedpiper.tests.csproj
piedpiper.website/piedpiper.website.csproj
So far so good!
Adding a project reference to a project
Next up we want to start adding project references to our project, linking our domain library to our website and test library via the dotnet add reference
command:
# /src/
$ dotnet add piedpiper.tests reference piedpiper.domain/piedpiper.domain.csproj
Reference `..\piedpiper.domain\piedpiper.domain.csproj` added to the project.
Now if you were to view the contents of your test project we’d see our domain library has now been referenced:
# /src/piedpiper.tests/
$ cat piedpiper.tests/piedpiper.tests.csproj
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup>
<ProjectReference Include="..\piedpiper.domain\piedpiper.domain.csproj" />
</ItemGroup>
</Project>
Next we’ll do the same for our website project, so let’s go to our website folder and run the same command:
# /src/
$ dotnet add piedpiper.website reference piedpiper.domain/piedpiper.domain.csproj
# /src/
$ cat piedpiper.website/piedpiper.website.csproj
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup>
<ProjectReference Include="..\piedpiper.domain\piedpiper.domain.csproj" />
</ItemGroup>
</Project>
At this point we’re done!
If we navigate back to our root source folder and run the build command we should see everything build successfully:
$ cd ../
# /src/
$ dotnet build
icrosoft (R) Build Engine version 15.3.388.41745 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
piedpiper.domain -> /Users/josephwoodward/Desktop/demo/src/piedpiper.domain/bin/Debug/netstandard2.0/piedpiper.domain.dll
piedpiper.tests -> /Users/josephwoodward/Desktop/demo/src/piedpiper.tests/bin/Debug/netcoreapp2.0/piedpiper.tests.dll
piedpiper.website -> /Users/josephwoodward/Desktop/demo/src/piedpiper.website/bin/Debug/netcoreapp2.0/piedpiper.website.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:08.08
Adding a NuGet package to a project or updating it
Before wrapping up, let’s say we wanted to add a NuGet package to one of our projects, we can do this using the add package
command.
First navigate to the project you want to add a NuGet package to:
# /src/
$ cd pipedpiper.tests/
$ dotnet add package shouldly
info : Adding PackageReference for package 'shouldly'
...
log : Installing Shouldly 2.8.3.
Optionally we could specify a version we’d like to install using the version argument:
$ dotnet add package shouldly -v 2.8.2
Updating a NuGet package
Updating a NuGet package to the latest version is just as easy, simply use the same command without the version argument:
dotnet add package shouldly
Conclusion
If you’ve managed to get this far then well done, hopefully by now you’ve realised how easy creating and managing a solution is using the new .NET Core command line interface.
One of the great powers of using the CLI is you can now turn creating the same project structure into a handy bash script which you could alias and reuse!
#!/bin/bash
echo "Enter project name, followed by [ENTER]:"
read projname
echo "Creating solution for $projname"
dotnet new sln -n $projname
dotnet new mvc -o $projname.website
dotnet new classlib -o $projname.domain
dotnet new xunit -o $projname.tests
echo "Adding projects to solution"
dotnet sln add **/*.csproj
echo "Referencing projects"
dotnet add $projname.website reference $projname.domain/$projname.domain.csproj
dotnet add $projname.tests reference $projname.domain/$projname.domain.csproj
Happy coding!
Enjoy this post? Don't be a stranger!
Follow me on Twitter at @_josephwoodward and say Hi! I love to learn in the open, meet others in the community and talk Go, software engineering and distributed systems related topics.