Do you use Directory.Build.Props to simplify multi-project build configurations?
Updated by Daniel Mackay [SSW] 9 months ago. See history
123
When working on large enterprise scale projects .NET Solutions can often become unwieldy and difficult to maintain. This is particularly true of `.csproj` files which end up repeating configuration across all projects. How can one file save you hours of maintenance by keeping project configuration DRY? ## What is a Directory.Build.props file? A [Directory.Build.props](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory?view=vs-2022) file is an MSBuild file used in .NET projects to define common properties and configurations that apply to multiple projects within a directory tree. This file helps centralize the configuration and reduce redundancy by allowing you to specify settings that will be inherited by all projects under the directory where the file is located. ### Usages This can be used for: * .NET framework version * Nullability * Implicit references * Configuring warnings as errors * Static code analysis * Author / Company ### Examples <asideEmbed variant="greybox" body={<> **Project1.csproj:** ```xml <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <!-- Configure code analysis. --> <AnalysisLevel>latest</AnalysisLevel> <AnalysisMode>Recommended</AnalysisMode> <TreatWarningsAsErrors Condition="'$(Configuration)' == 'Release'">true</TreatWarningsAsErrors> <CodeAnalysisTreatWarningsAsErrors Condition="'$(Configuration)' == 'Release'">true</CodeAnalysisTreatWarningsAsErrors> <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> </PropertyGroup> </Project> ``` **Project2.csproj:** ```xml <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <!-- Configure code analysis. --> <AnalysisLevel>latest</AnalysisLevel> <AnalysisMode>Recommended</AnalysisMode> <TreatWarningsAsErrors Condition="'$(Configuration)' == 'Release'">true</TreatWarningsAsErrors> <CodeAnalysisTreatWarningsAsErrors Condition="'$(Configuration)' == 'Release'">true</CodeAnalysisTreatWarningsAsErrors> <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> </PropertyGroup> </Project> ``` </>} figureEmbed={{ preset: "default", figure: 'XXX', shouldDisplay: false }} /> <figureEmbed figureEmbed={{ preset: "badExample", figure: 'Bad example - Redundant configuration', shouldDisplay: true } } /> <figureEmbed figureEmbed={{ preset: "goodExample", figure: '**Project1.csproj:** ```xml <Project Sdk="Microsoft.NET.Sdk.Web"> </Project> ``` **Project2.csproj:** ```xml <Project Sdk="Microsoft.NET.Sdk.Web"> </Project> ``` **Directory.Build.props:** ```xml <Project> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <!-- Configure code analysis. --> <AnalysisLevel>latest</AnalysisLevel> <AnalysisMode>Recommended</AnalysisMode> <TreatWarningsAsErrors Condition="\'$(Configuration)\' == \'Release\'">true</TreatWarningsAsErrors> <CodeAnalysisTreatWarningsAsErrors Condition="\'$(Configuration)\' == \'Release\'">true</CodeAnalysisTreatWarningsAsErrors> <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> </PropertyGroup> </Project> ```', shouldDisplay: true } } /> <figureEmbed figureEmbed={{ preset: "goodExample", figure: 'Good example - Centralized configuration', shouldDisplay: true } } />