MSBuild Tool for .NET Projects

MSBuild is the build engine that ships with .NET and Visual Studio, and it is the layer most developers never want to touch until a CI pipeline fails in a way their machine cannot reproduce. The XML, the property functions, the implicit ordering of targets, the difference between $(Property) evaluation at static and dynamic time — none of it is intuitive, all of it matters, and the documentation is scattered across two decades of release notes.

The articles in this collection cover the parts of MSBuild that actually break builds in production. TargetFramework conditions are a recurring source of pain: a string comparison like '$(TargetFramework)' == 'net8.0' looks correct and fails silently on net8.0-windows, net8.0-android, or any future TFM that adds a platform suffix. The IsTargetFrameworkCompatible() property function understands framework semantics and prevents the multi-targeting regressions that string comparisons quietly introduce.

Analyzer and warning management gets a dedicated thread because most projects inherit a baseline of tens of thousands of warnings they have no realistic plan to fix. The articles document the strategy that actually works: ratchet-style enforcement with WarningsAsErrors, NoWarn lists scoped to individual files rather than the whole project, and .editorconfig overrides that distinguish between legacy code and new development. Suppressing warnings is the easy answer; managing them sustainably is the engineering one.

Central package management with Directory.Packages.props, custom .props and .targets files that load before the SDK, and the build customization extension points that let teams enforce conventions without copy-paste across every .csproj round out the collection.

A final cluster examines what happens inside Visual Studio specifically — design-time builds, NuGet PackageDownload semantics, and the differences between IDE and command-line builds that explain why so many problems only reproduce in one environment.

Stop Breaking Multi-Targeting Builds with String Comparisons

Stop Breaking Multi-Targeting Builds with String Comparisons

String-based TargetFramework conditions fail silently in multi-targeting builds. IsTargetFrameworkCompatible() understands framework semantics and prevents production nightmares.
PackageDownload: NuGet's Forgotten Power Tool

PackageDownload: NuGet's Forgotten Power Tool

PackageDownload arrived in NuGet 4.8 to solve a niche but genuine problem: downloading packages without adding assembly references. It works. But its version syntax requirements and complete disregard for Central Package Management reveal the messy reality of platform evolution.
Managing Errors, Warnings, and Configurations in C# and .NET

Managing Errors, Warnings, and Configurations in C# and .NET

When we activated static code analysis for the first time in one of my last projects, the overwhelming number of warnings exceeded expectations and highlighted gaps in the code. Without making any changes, the project already had a significant number of warnings. After activating additional analyzers and updating some configurations, this number temporarily increased dramatically.

The high number of warnings was initially daunting, but we saw it as an opportunity to significantly improve our code quality. At first glance, it seemed easier to suppress or ignore these warnings. But as I often remind my team, “The code you create is a valuable legacy, so it’s important to build it carefully.” Ignoring warnings today creates obstacles for future developers—and that could very well include you six months down the line.

This experience reinforced the importance of managing warnings and errors systematically. Let me share some of the lessons we learned, the strategies we used to tame those 60,000 warnings, and how you can apply these techniques to your own projects.

BuildingInsideVisualStudio: .NET Project Properties

BuildingInsideVisualStudio

In the ever-evolving world of .NET development, managing project configurations effectively is crucial for maintaining a clean and efficient build process. One of the less frequently discussed but highly useful properties is BuildingInsideVisualStudio. This property, when correctly utilized, can streamline your build process and ensure that your project is configured properly depending on the build environment. In this article, we’ll explore the BuildingInsideVisualStudio property with concrete examples and discuss best practices for using it effectively.