Monorepo with C#: Code Organization and Best Practices
In modern C# (.NET) development, the monorepo approach is increasingly used. Unlike multi-repositories, where each project lives in its own Git repository, a monorepo stores all company or product code in one central repository. For .NET developers, this means a single solution, shared libraries, and simplified CI/CD setup. In this article, we will look at how to properly organize a monorepo with C#, provide code examples, and discuss key advantages.
1. Advantages of a Monorepo for .NET
A monorepo is especially useful for teams working on multiple related .NET projects: microservices, web applications, class libraries. Main benefits:
- Single version of dependencies — all projects use the same versions of NuGet packages, eliminating conflicts.
- Simplified refactoring — changing a common interface or data model is immediately applied to all consumers.
- Shared Git history — atomic commits affecting multiple projects are visible in one place.
- Centralized CI/CD — one pipeline for building, testing, and deploying all components.
For C#, a monorepo is built around a single .sln file (solution) that references all projects. This allows using built-in Visual Studio and .NET CLI tools for dependency management.
2. Monorepo Structure for C#
Let's consider a typical monorepo structure for a .NET solution. It might look like this:
MyCompany/├── src/│ ├── MyCompany.Common/ # Shared library│ │ ├── MyCompany.Common.csproj│ │ └── ...│ ├── MyCompany.WebApi/ # Web API│ │ ├── MyCompany.WebApi.csproj│ │ └── ...│ └── MyCompany.BackgroundJob/ # Background service│ ├── MyCompany.BackgroundJob.csproj│ └── ...├── tests/│ ├── MyCompany.Common.Tests/│ ├── MyCompany.WebApi.Tests/│ └── MyCompany.BackgroundJob.Tests/├── docs/ # Documentation├── scripts/ # Scripts for CI/CD├── .gitignore└── MyCompany.sln # Single solutionKey elements of this structure:
- src/ — folder with source code. Each project is a separate folder with its own .csproj file.
- tests/ — folder with tests. Test project names mirror the main ones with the .Tests suffix.
- docs/ — documentation (README, architectural decisions).
- scripts/ — scripts for build or deployment automation.
- MyCompany.sln — single solution file that includes all projects.
This structure simplifies navigation and allows easily adding new projects without changing the root configuration.
3. Setting Up a Single Solution and Shared Dependencies
To create a monorepo in .NET, use the dotnet new sln command, then add projects:
# Create root folder and navigate into itmkdir MyCompany && cd MyCompany
# Create empty solution filedotnet new sln -n MyCompany
# Create folder structuremkdir src tests docs scripts
# Create projectsdotnet new classlib -n MyCompany.Common -o src/MyCompany.Commondotnet new webapi -n MyCompany.WebApi -o src/MyCompany.WebApidotnet new console -n MyCompany.BackgroundJob -o src/MyCompany.BackgroundJob
# Add projects to solutiondotnet sln add src/MyCompany.Common/MyCompany.Common.csprojdotnet sln add src/MyCompany.WebApi/MyCompany.WebApi.csprojdotnet sln add src/MyCompany.BackgroundJob/MyCompany.BackgroundJob.csprojNow let's add a reference to the shared library from the Web API: