Monthly Archives: April 2019

Partial csproj files simplify your NuGet dependencies

Recently I learned about a pretty simple feature that is super useful when working with .NET solutions that have several .csproj files, and the same NuGet package dependency in two or more of them.

The simple way to do this —what Visual Studio’s “Manage Nuget package” dialog does— is to add/update PackageReference elements in each csproj, like this:

separate-nuget-refs

Separate references to the same Nuget package in different projects

But this means that whenever you want to update this dependency, you need to do it separately in each project… and I hope you don’t have too many of them.

The DRY way to do this, is with Import elements in the csproj file, that reference other (partial) csproj files, like this:

common-nuget-refs

Shared, partial, .csproj file referenced by other .csproj files

Note that I used .csproj.include for the shared csproj file; the extension doesn’t actually matter.

Now whenever you need to update that dependency, you can do it in a single place and all the projects that reference that file will keep their versions in sync.

The only caveat I’ve found with this method is that Visual Studio’s “Manage Nuget packages” dialog doesn’t play well with it. If you use it in any particular project to update the package defined in the common file, a new PackageReference will be added to that project file, and the Import statement will remain. This won’t cause a build error, but depending on the order of the PackageReference and Import elements in your project file, might end up causing one or other version of the package to be used. So make sure that your whole team understands how these shared dependencies packages need to be updated going forward.

Don’t use a variable named TMP in your scripts that call the dotnet CLI

For a long time now, I had a script where I was passing --no-build to a dotnet test command, because otherwise it got stuck in a very weird way. The tests never started running (in fact the build never finished), and if I hit Ctrl-C to stop it, even though it apparently stopped, something kept running in the background and printing warnings to my console, on top of whatever else I was doing.

build stuck warnings

I googled keywords from the warning and couldn’t find anything relevant. Today I had to deal with this script again and decided to fix it once and for all.

For context, this is a bash script that runs on Windows (with Git Bash) and basically does the following:
– Start a test environment with several containers using docker-compose.
– Figure out which ports were exposed on the host for some of those containers and export them as environment variables (so the project being run with dotnet test sees them).
– Run dotnet test to execute the tests in a project.
– Use docker-compose to remove the environment we spun up earlier.

So I started troubleshooting my dotnet test command.

It ran fine outside the script, and also by itself inside an .sh file. So I started adding all the other pieces of the script little by little, until I found the one that made dotnet test hang. It was a line pretty much identical to this:

TMP=$(docker port ${PROJECT_NAME}_myservice_1 80)

That’s (part of) how I get the port that was exposed for a particular container, but I refused to believe that executing docker port had anything to do with the problem. So I tried renaming TMP to TMP_PORT_INFO… and what do you know, the script didn’t get stuck anymore!

I couldn’t find any official documentation about this, but it seems like dotnet build (which dotnet test runs implicitly) depends on the TMP variable to be a path to a temporary storage location for the system. A bit of research made me think that in UNIX, the relevant variable is TMPDIR, but in Windows it’s TMP.

So there you have it. If you want to avoid some painful troubleshooting, just don’t use TMP as a variable name in your scripts.