Fixing analyzer problems in multi-targeted Umbraco packages

As many of you may know, I've recently been working on getting Vendr ready for Umbraco v9 which is based on .NET Core. As we blogged about, because we need to continue to support v8 users of Umbraco we took the decision to do a multi-targeted approach whereby we would have a single package that contains DLL's compiled for both .NET Framework (v8) and .NET Core (v9) and have the correct ones be used depending on the project it is installed into.

Whilst most of the setup for multi-targeting worked as expected, there was one weird bug that we couldn't quite figure out. We managed to find a hacky way around it, and just moved on, but as more Umbraco package devs are starting to make the move to .NET Core, and some of those are also looking at multi targeted approaches, I'm seeing those devs hit the exact same problem too, so I thought I'd look into more and see if there is proper fix.

The Problem

The problem I was witnessing was that my projects that had an Umbraco dependency would also inherit a dependency on Lucene.NET. For the .NET Framework target this would be Lucene.NET v3 and for the .NET Core target this would be Lucene.NET v4.

The issue was, that the v4 build of Lucene.NET contained some code analyzers which the v3 build didn't have, however the SDK project implementation, which automatically includes analyzers into your project, would assume that if one build had the analyzers, then both builds must have them, and so analyzers would appear in both analyzers collections for both targets.

Unfortunately though, because the v3 build didn't actually have any of them, when you'd come to build the project, you would get build errors.

Original Hacky Workaround

I did some investigation and tried a number of things to try and make this work initially, but nothing I did seemed to work.

The only thing I could get to work, and what many of the other Umrbaco package devs started doing was to copy the analyzers DLLs from the v4 nuget package folder to the v3 folder.

This worked, and prevented the build errors, but it wasn't ideal. Especially if you have a build server build your packages as I ended up having to put some code in my build script to auto copy the analyzers after nuget package restore which was really pretty ugly.

Reporting The Issue

I was originally reluctant to report this issue as I couldn't really narrow down what was at fault. Was it Visual Studio? or was it .NET?

After some discussions with others, we came to the conclusion it must be .NET at fault so I went and reported the issue on GitHub.

Thankfully we were correct that it was .NET Core, or more specifically, the SDK project implementation that was at fault, and there was already a fix coming in .NET 6

A Better Workaround

A great thing from the issue tracker though was a suggested interim workaround which was much less hacky than the approach I had previously been doing and was a simple case of updating your proj file with the following snippet to remove the offending analyzer

<!-- Workaround for this bug (replace the analyzer name with the one you need to exclude (filename only, no extension) -->
<Target Name="RemoveLuceneAnalyzer" BeforeTargets="CoreCompile">
        <Analyzer Remove="@(Analyzer)" Condition="%(FileName) == 'Lucene.Net.CodeAnalysis.CSharp'" />

Well, this worked great and is now the approach I'm using in all my affected projects.

Hopefully this won't be needed when .NET 6 gets released, but we at least have a decent workaround in the meantime.

I hope this helps other Umbraco package devs who also hit the same problem whilst multi-targeting.