<- Back

posh.wiki / blog


Useful Files For Your Repository: .NET Edition

This post is a follow-up to my earlier post, Useful Metadata Files For Your Repository. While that post tried its best to be language and tooling-agnostic, this edition specialises in lesser known utilities for .NET developers.

global.json

For .NET Core 3.1 SDK and later, the global.json file contains a definition for which SDK versions should be used when using the dotnet CLI command.

As the name implies, the file contains json data (specifically, JSON with comments), which must follow a specific schema.

The below example dictates that within the directories src/ and test/, the .NET SDK used must be version 8.0.300 exactly.

json { "sdk": { "version": "8.0.300", "rollForward": "disable", "allowPrerelease": false, "paths": ["src/", "test/"], "errorMessage": "A suitable .NET SDK could not be found" } }

Directory.Build.props, Directory.Build.targets

Directory.Build.props and Directory.Build.targets are XML files, much like a .csproj file, which contain additional information for C# projects in a given directory and its subdirectories. In these files, you can specify just about anything you'd specify in a csproj file.

The difference between them is the time at which they're loaded: Directory.Build.props is loaded early, and its settings can be overwritten by a .csproj file, while Directory.Build.targets is loaded later, and overwrites rules in a .csproj. One could think of .props more as suggestions, and .targets as strict rules.

MSBuild.rsp, Directory.Build.rsp

These response files contain CLI arguments to be passed automatically to MSBuild when it's called.

When MSBuild.exe is run, it will automatically load in MSBuild.rsp from the current directory. Since MSBuild version 15.6, it will also search for Directory.Build.rsp in parent directories, which follows the same format.

For example, to always show the most verbose logs possible, but disable the startup banner and copyright message, one might use:

shell -verbosity:diagnostic -nologo

To ignore these response files when running MSBuild, the -noAutoResponse (or -noautorsp) flag can be passed.

Directory.Pakages.props

Directory.Pakages.props is an alternative to using <PackageReference /> in a .csproj file (or packages.config for older projects). Since NuGet 6.2, dependeniees can be managed centrally using a single file.

In truth, this file applies to all MSBuild projects which can use a <PackageReference />, even retrospectively. So long as compatible tooling is used, one could use this file with legacy .csproj files, VB or F# projects, and more.

This file can be created automatically form a template using dotnet new packagesprops. The contents should look something like this:

xml <Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> </PropertyGroup> <ItemGroup> <PackageVersion Include="Newtonsoft.Json" Version="13.0.1" /> </ItemGroup> </Project>

It's important to note that this file's rules don't cascade. Once one Directory.Pakages.props file is found, no more in higher directories are considered.

It's also worth mentioning that this file is often largely redundant for smaller repositories. Well-architected small solutions often don't require multiple projects to share references in this way. Try not to use this file just for the sake of it.

nuget.config

The nuget.config file is an XML file that contains configuration information for the NuGet package manager. In its most basic form, it looks like this:

```xml

```

This file can define custom package sources, to save developers the effort of setting up new custom sources after cloning the repository for the first time.

xml <packageSources> <add key="nuget" value="https://api.nuget.org/v3/index.json" /> <add key="Custom" value="https://my.custom.nuget.feed.xyz/v3/index.json" /> </packageSources>

Additionally, <clear /> can be used to clear any system-wide package sources, ensuring that there are no conflicts, and saving developers the trouble of having to sign into, disable, or skip unused sources.

xml <packageSources> <clear /> <add key="nuget" value="https://api.nuget.org/v3/index.json" /> </packageSources>

Similarly, it can defend against the user disabling sources that are explicitly included in the file.

xml <disabledPackageSources> <clear /> </disabledPackageSources>

Package source mapping can be used to hint as to which packages should be retrieved from which sources. This can help resolve conflicts and reduce redundant requests.

xml <packageSourceMapping> <packageSource key="nuget"> <package pattern="*" /> </packageSource> <packageSource key="Custom"> <package pattern="My.Custom.Package" /> </packageSource> </packageSourceMapping>

Honourable Mention: Dockerfile, .dockerignore

While Docker isn't strictly to do with the .NET ecosystem, it can still be a powerful tool to avoid the "it works on my machine" problem, as is one of the benefits of many of the files listed above.

While it won't enable MacOS and Linux users to run projects that rely on Windows-specific functionality (because Windows containers can only be run on Windows machines), it can still help to manage versions and environments, and it's worth considering especially for web and API projects.

Further Reading

For global.json, consider the global.json overview for more information about the schema.

For Directory.Build files, Customize the build by folder contains significantly more information than the brief overview in this article.

For autoresponse files, MSBuild response files describes the function of the files, while MSBuild command-line reference contains an exhasustive list of the options available.

For Directory.Packages.Props, Central Package Management (CPM) also explains some more in-depth options not touched on by this post.

For nuget.config, the nuget.config reference describes a variety of options beyond just configuring sources.

Finally, for those wanting to try Docker, Tutorial: Containerize a .NET app is a good starting point.