Multiple Projects with .Net Core and Visual Studio Code

The challenge is to create a solution in VS Code with multiple projects. There are three projects

  1. A console application
  2. A web api application
  3. A library with data access code that is common to both.

It will look like this when we are finished

Expanded to show detail

We need a solution that can build out all these projects in one click. Since we using VS Code and enjoying it’s lightweightness we’ll be relying completely on the new .Net Core Command Line Interface. I enjoy a challenge so using the command line seems fun (to me). Let’s go.

(TL;DR;)

In case you don’t want to read the detail – the commands used to set up all projects, solutions and references are

From project root

dotnet new console -o Demo.ConsoleApp

dotnet new classlib -o Demo.Common

cd Demo.ConsoleApp

dotnet add reference ../Demo.Common/Demo.Common.csproj

dotnet add package MyPackage

cd ../

dotnet new webapi -o Demo.Api

cd Demo.Api

dotnet add reference ../Demo.Common/Demo.Common.csproj

cd ../

dotnet new sln -n Demo

dotnet sln add Demo.ConsoleApp/Demo.ConsoleApp.csproj

dotnet sln add Demo.Api/Demo.Api.csproj

dotnet build

Preliminary

To do this you’ll need VS Code’s C# extension installed into visual studio. Go to extensions and search for C#.

Install and away you go.

Note on command line

All .Net Core CLI commands can be entered into the terminal window in VS Code or into the standard command prompt if you prefer. Navigate to the root folder and enter your first command

Create Console Application

dotnet new console -o Demo.ConsoleApp

This installs our console application project. Since we are on .Net Core 2.0 we get the csproj file rather than the json project file of earlier versions. This installs the console app in a new folder with the same name as it’s containing folder. If we want a different name to the folder we do that by

dotnet new console -n MyProjectName -o Demo.ConsoleApp

But we don’t want that. We are keeping it simple. What I like about .Net Core is that it’s had all the gubbins stripped out. So our proj file for the console app is simply …

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <ProjectReference Include="..\Demo.Common\Demo.Common.csproj" />
  </ItemGroup>
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>
</Project>

Nice. I understand that.

Create Common Library

Next we want to create a C# dll to host some common code like data access.

dotnet new classlib -o Demo.Common

Creates an empty project called Demo.Common with a nice simple proj file thus

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
</Project>

Link Common Library to Console app

Change to the console app direct and run the add reference common

cd Demo.ConsoleApp
dotnet add reference ../Demo.Common/Demo.Common.csproj

Inserts the following into the console proj file

  <ItemGroup>
    <ProjectReference Include="..\Demo.Common\Demo.Common.csproj" />
 </ItemGroup>

So the console app can access code in the common project and the two will build out together.

Add Nuget package to Common Library

We commonly want to add some nuget packages to our projects. So lets add the HtmlAgility pack and a C# driver for MongoDB – no reason for them other than I often use them.

Change directories back to common library

 cd ../Demo.Common

Now add the packages

dotnet add package MongoDB.Driver
dotnet add package HtmlAgilityPack

Look at the proj file and you can see the package references inserted

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="HtmlAgilityPack" Version="1.6.5" />
    <PackageReference Include="MongoDB.Driver" Version="2.4.4" />
  </ItemGroup>
</Project>

VS Code likes to tell me to restore the project I.e. run dotnet restore. You don’t need to. Dotnet build or dotnet run does it for you.

Build Console Application

Let’s check things are working as they should and build our console app.

cd ../Demo.ConsoleApp
dotnet build

Output

  Demo.Common -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Common\bin\Debug\netstandard2.0\Demo.Common.dll

Demo.ConsoleApp -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.ConsoleApp\bin\Debug\netcoreapp2.0\Demo.ConsoleApp.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Good – by building the project we get both common and the console application building.

Create API 

Return to root folder

cd ../

Now add a web api project called Demo.Api

dotnet new webapi -o Demo.Api

Change to the Api folder

cd Demo.Api

Now add a reference to our common library

dotnet add reference ../Demo.Common/Demo.Common.csproj

The Api proj file looks a bit more complex but I’ll still pretty minimal compared to Visual Studio proj files.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\Demo.Common\Demo.Common.csproj" />
  </ItemGroup>
</Project>

Now let’s build that project. Staying in the Api folder

dotnet build

And the output shows us two projects have been built.

  Demo.Common -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Common\bin\Debug\netstandard2.0\Demo.Common.dll

Demo.Api -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Api\bin\Debug\netcoreapp2.0\Demo.Api.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Joining everything together

Ok , so we want all the projects to build in one click. Because we have two independent applications (an API and a console app) we aren’t going to be able to do the build by navigating to a folder and building the proj file. We need a solution file to bind them all together

(this shamefully baffled me for a while. I was trying all sorts with launch.json etc… The solution is obvious though – embarrassed for not getting it immediately)

Back to root

cd ../

Now add the solution file. We don’t want it in it’s own directory so omit the -o parameter. Add in the -n otherwise it takes it’s name from the containing folder which we don’t want in this case.

dotnet new sln -n Demo

Now include the API and Console app

dotnet sln add Demo.ConsoleApp/Demo.ConsoleApp.csproj
dotnet sln add Demo.Api/Demo.Api.csproj

The solution file now includes the project info

Microsoft Visual Studio Solution File, Format Version 12.00

# Visual Studio 15

VisualStudioVersion = 15.0.26124.0

MinimumVisualStudioVersion = 15.0.26124.0

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.ConsoleApp", "Demo.ConsoleApp\Demo.ConsoleApp.csproj", "{FDFFDD15-D0C0-4D66-9694-B21D85DBA5AE}"

EndProject

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Api", "Demo.Api\Demo.Api.csproj", "{C1B9391B-07FC-403A-AA46-41128BC1FD07}"

EndProject

Staying in the solution directory run build

dotnet build

And now all three projects are built.

Demo.Common -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Common\bin\Debug\netstandard2.0\Demo.Common.dll

Demo.ConsoleApp -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.ConsoleApp\bin\Debug\netcoreapp2.0\Demo.ConsoleApp.dll

Demo.Api -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Api\bin\Debug\netcoreapp2.0\Demo.Api.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Finished!!!

Demo code

The rather uninspiring skeleton demo app is at
https://github.com/timbrownls20/Demo/tree/master/ASP.NET%20Core/MultipleProjects

More interesting the same pattern is on a .Net Core API for some Buddhist texts I’ve been working on
https://github.com/timbrownls20/Pali-Canon/tree/master/Api

So

https://github.com/timbrownls20/Pali-Canon/tree/master/Api/PaliCanon.Loader
Is the console app that parses HTML and populates a document database with the texts

https://github.com/timbrownls20/Pali-Canon/tree/master/Api/PaliCanon.Api
Is the web api to access the texts

https://github.com/timbrownls20/Pali-Canon/tree/master/Api/PaliCanon.Common
Is the model and repositories common to both.  It’s the same pattern as the simplified demo app and I’m using VS Code for that – just to try it out really.

Useful Links

https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x
Full documentation for .Net Core Command Line Interface

https://code.visualstudio.com/download
Visual Studio Code is freely available here.