I'd like to make define a symbol NEWTONSOFT
if (and only if) the Newtonsoft.Json NuGet package is added as a PackageReference to my .NET Core app. How can I do that?
EDIT: To clarify, I'd like add the symbol, if the reference is present. And if I delete the reference, the symbol should no longer be defined - but I should not manually add/remove the symbol definition. Something like this:
<Choose>
<When Condition=" '$(PackageReference).Identity'=='Newtonsoft.Json' ">
<PropertyGroup>
<DefineConstants>HDN</DefineConstants>
</PropertyGroup>
</When>
</Choose>
Except this does not work.
A way to do this sort of automatically is including a target that contributes build logic into your csproj file like this:
<Target Name="AddPackageSpecificConstants" BeforeTargets="BeforeCompile">
<PropertyGroup>
<DefineConstants Condition="@(Reference->AnyHaveMetadataValue('NuGetPackageId','Newtonsoft.Json'))">$(DefineConstants);NEWTONSOFT_JSON</DefineConstants>
<DefineConstants Condition="@(Reference->AnyHaveMetadataValue('NuGetPackageId','YamlDotNet '))">$(DefineConstants);YAML_DOT_NET</DefineConstants>
</PropertyGroup>
</Target>
By hooking into the build process this can detect if your code has any compile-time references (meaning the API surface of the pacakges is available in your C# code) to specific NuGet packages, even if they are only transitively referenced (e.g. you reference a library that references Newtonsoft.Json so your could can use it).
By doing definitions like <X>$(X);</X>
the additional constants are added to the property so this leavs intact anything the SDK gives you by default based on the target framework or your other project contents.