1. What is it?
In Azure DevOps, we can use a single YAML pipeline to build and test multiple .NET projects within the same solution.
For example, an ASP.NET Core application using Clean Architecture may contain:
-
API – ASP.NET Core Web API.
-
Application – Business logic and services.
-
Domain – Entities and domain rules.
-
Infrastructure – Database and external integrations.
-
UnitTests – Automated unit tests.
-
IntegrationTests – Integration tests.
Instead of creating separate pipelines for every project, we can use one pipeline to restore, build, and test the entire solution.
Main advantages:
-
Centralized CI configuration.
-
Automatically builds project dependencies.
-
Runs multiple test projects.
-
Reduces pipeline maintenance.
-
Generates deployable artifacts for the required applications.
2. How Does It Work?
Consider this .NET solution:
MyApplication/
│
├── src/
│ ├── MyApp.API/
│ │ └── MyApp.API.csproj
│ │
│ ├── MyApp.Application/
│ │ └── MyApp.Application.csproj
│ │
│ ├── MyApp.Domain/
│ │ └── MyApp.Domain.csproj
│ │
│ └── MyApp.Infrastructure/
│ └── MyApp.Infrastructure.csproj
│
├── tests/
│ ├── MyApp.UnitTests/
│ │ └── MyApp.UnitTests.csproj
│ │
│ └── MyApp.IntegrationTests/
│ └── MyApp.IntegrationTests.csproj
│
├── MyApplication.sln
└── azure-pipelines.yml
Pipeline execution flow:
Developer Pushes Code
|
v
Azure DevOps CI Pipeline
|
v
Checkout Source Code
|
v
dotnet restore MyApplication.sln
|
v
dotnet build MyApplication.sln
|
+----> Domain
|
+----> Application
|
+----> Infrastructure
|
+----> API
|
+----> Test Projects
|
v
Run Unit Tests
|
v
Run Integration Tests
|
v
Publish MyApp.API
|
v
Generate Build Artifact
|
v
Available for Deployment
Important: When we build the .sln file, .NET automatically determines the appropriate build order based on project references.
We do not need to manually build Domain, Application, Infrastructure, and API separately.
3. Azure Pipelines YAML Example
The following pipeline builds the entire solution and executes both unit and integration tests.
trigger:
branches:
include:
- main
- develop
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
steps:
# 1. Checkout Source
- checkout: self
# 2. Install .NET SDK
- task: UseDotNet@2
displayName: 'Install .NET SDK'
inputs:
packageType: 'sdk'
version: '8.0.x'
# 3. Restore All Projects
- script: >
dotnet restore MyApplication.sln
displayName: 'Restore Solution'
# 4. Build All Projects
- script: >
dotnet build MyApplication.sln
--configuration $(buildConfiguration)
--no-restore
displayName: 'Build Entire Solution'
# 5. Run Unit Tests
- script: >
dotnet test tests/MyApp.UnitTests/MyApp.UnitTests.csproj
--configuration $(buildConfiguration)
--no-build
displayName: 'Run Unit Tests'
# 6. Run Integration Tests
- script: >
dotnet test tests/MyApp.IntegrationTests/MyApp.IntegrationTests.csproj
--configuration $(buildConfiguration)
--no-build
displayName: 'Run Integration Tests'
# 7. Publish Web API
- script: >
dotnet publish src/MyApp.API/MyApp.API.csproj
--configuration $(buildConfiguration)
--no-build
--output $(Build.ArtifactStagingDirectory)/api
displayName: 'Publish Web API'
# 8. Publish Pipeline Artifact
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)/api'
artifact: 'drop'
publishLocation: 'pipeline'
This example assumes the integration-test dependencies, such as a test database, are available. If those tests require SQL Server or other services, the pipeline must provision or connect to them securely.
4. Different Approaches to Building Multiple Projects
Approach 1: Build the entire solution (recommended for related projects)
dotnet restore MyApplication.sln
dotnet build MyApplication.sln --configuration Release
dotnet test MyApplication.sln --configuration Release --no-build
This builds every project included in the solution and runs tests from its test projects.
Best for: Clean Architecture applications with multiple class libraries, APIs, and test projects.
Approach 2: Build individual projects
steps:
- script: dotnet build src/MyApp.API/MyApp.API.csproj
displayName: 'Build API'
- script: dotnet build src/MyApp.Application/MyApp.Application.csproj
displayName: 'Build Application'
Best for: Projects that require different build settings or independent build processes.
Note that building the API project already builds its referenced projects when required, so explicitly building those dependencies again is often unnecessary.
Approach 3: Use separate jobs for independent applications
jobs:
- job: BuildAPI
steps:
- script: dotnet build src/MyApp.API/MyApp.API.csproj
displayName: 'Build API'
- job: BuildWorker
steps:
- script: dotnet build src/MyApp.Worker/MyApp.Worker.csproj
displayName: 'Build Worker'
Independent jobs can run in parallel when sufficient agents are available. Each job runs in its own execution environment, so it must have the required SDK and dependencies available.
Best for: Solutions containing multiple independently deployable applications.
5. Comparison of Approaches
|
Approach |
How it works |
Best use case |
|---|---|---|
|
Solution-level build |
Builds all projects in |
Clean Architecture |
|
Individual project build |
Builds selected |
Selective compilation |
|
Multiple jobs |
Builds applications independently |
Multiple APIs or services |
|
Matrix strategy |
Runs builds across configurations |
Multiple SDKs or operating systems |
6. What Happens If One Project Fails?
Suppose the solution contains four application projects and two test projects.
Domain → Passed
Application → Passed
Infrastructure → Failed
API → Not Successfully Built
Unit Tests → Skipped
Integration → Skipped
Publish → Skipped
If Infrastructure contains a compilation error, dotnet build MyApplication.sln fails.
The pipeline normally stops executing dependent steps, so the application artifact is not published.
Similarly, if unit or integration tests fail, the publish step is skipped under the default pipeline conditions.
7. Important Interview Questions
Q1. Can we build multiple .NET projects using one Azure Pipeline?
Yes. We can build an entire .sln file or specify multiple project files in the pipeline.
Q2. Do we need separate build commands for Domain, Application, Infrastructure, and API?
No. If these projects are included in the solution, dotnet build MyApplication.sln builds them in the correct dependency order.
Q3. Can we run multiple unit-test projects in one pipeline?
Yes. We can execute dotnet test against the solution or run individual test projects using separate steps.
Q4. Can multiple .NET projects build in parallel?
Yes. Independent projects can be built in separate jobs, potentially running in parallel depending on agent availability.
Q5. What happens if one project fails compilation?
The solution build fails. Subsequent dependent test and publish steps normally do not execute.
Q6. Should every class library generate a deployment artifact?
No. Normally, only deployable applications such as Web APIs, web applications, and worker services need deployment artifacts. Referenced class libraries are included in the published application's dependencies.
Q7. Can one pipeline generate multiple artifacts?
Yes. For example, a pipeline can publish api-drop for a Web API and worker-drop for a background worker.
8. Interview-Ready Answer
In Azure DevOps, I use a single YAML pipeline to build and test multiple .NET projects within the same solution.
For example, in a Clean Architecture application containing API, Application, Domain, Infrastructure, and test projects, I first run
dotnet restoreagainst the solution file.Next, I execute
dotnet build MyApplication.slnin Release mode, which automatically builds all projects based on their dependencies.After successful compilation, I use
dotnet testto execute unit and integration tests. If any build or mandatory test fails, the pipeline stops and prevents artifact publishing.Finally, I use
dotnet publishfor the deployable Web API project and upload the output usingPublishPipelineArtifact@1.For multiple independent applications, I can use separate jobs to build them in parallel and generate individual deployment artifacts.
Key sequence to remember:
One Solution (.sln)
|
v
Restore All Projects
|
v
Build All Projects
|
v
Run All Tests
|
v
Publish Deployable Projects
|
v
Generate Pipeline Artifacts
Most important interview point: For a typical ASP.NET Core Clean Architecture solution, use a solution-level restore and build, execute the required test projects, and publish only the deployable applications.