Search code examples
c#wpfmsbuildconditional-statementsmsbuild-task

How to conditionally compile a NuGet package on build in a WPF project?


I'm using a NuGet package in the project. Is there a way to isolate or ignore that NuGet package and use another NuGet package using a compile switch or Macro?

Purpose: This NuGet Package is licensed per developer, So the intent is to disconnect it during the development from other developers.

I have looked into myproject.csproj

...
<ItemGroup>
    <PackageReference Include="nugetPackage2Exclude" Version="1.0.0.0">
        <ExcludeAssets>none</ExcludeAssets>
    </PackageReference>
...

But, I could not make it work using a compile switch or macro.


Solution

  • After a lot of tinkering. This is the final solution that turned out to satisfy all my requirements. It is a bit long and I have added all the findings relevant to this question.

    Before I get into implementation, this is my setup #(.NET 6.0, C# 10, WPF Project, VS2022)

    Steps involved!

    1. Declaration of a compile switch
    2. Prebuild conditional switch for compiling/ignoring the Nuget Package
    3. Context switch in the XAML file.
    4. Compile switches to isolate the package in the C# file.

    Step1: Declaration of a compile switch (NUGET_ENABLE)

    Project -> Proprties -> Conditional Compilation Symbols

    $(DefineConstants);NUGET_ENABLE
    

    (Note: A value cannot be assigned to the NUGET_ENABLE, The NUGET_ENABLE has to be renamed or removed for Removing this NuGet Usage.)

    Step2: Prebuild conditional switch for compiling/ignoring the Nuget Package

    Open the myproject.csproj (Project file). Use a regex expression to find the specific compile switch from $(DefineConstants), If NUGET_ENABLE exists compile the NuGet package.

    (Reference: MS Docs)

        <Choose>
        <When Condition="$([System.Text.RegularExpressions.Regex]::IsMatch($(DefineConstants), '^(.*;)*NUGET_ENABLE(;.*)*$'))">
            <!-- When NUGET_ENABLE is defined. -->
            <ItemGroup>
                <PackageReference Include="nugetPackage2Exclude" Version=""/>
            </ItemGroup>
        </When>
        </Choose>
    

    Step3: Context switch in the XAML file

    (Fair Warning!: The <mc:AlternateContent> Tag may prevent the loading of the Design preview window (Xaml Designer) in VS or Blend.)

    (Reference: this question)

    Step3a: Edit the assembly file to add a XAML Switch

    #if NUGET_ENABLE 
    [assembly: XmlnsDefinition("nuget_enable", "NameSpace")]
    #endif // NUGET_ENABLE
    

    Step3b: Add the XAML file headers

        ...
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:nuget="http://schemas.nugetPackage2Exclude.etc/"
         xmlns:nugetEnabled="nuget_enable"
        ...
         mc:Ignorable="d nuget" // d is optional!
        ...
    

    Step3c: Add the XAML context switch

        <mc:AlternateContent>
            <mc:Choice Requires="nugetEnabled">
                    <!--<code calling the nuget>-->
            </mc:Choice>
            <mc:Fallback>
            
            </mc:Fallback>
        </mc:AlternateContent>
    

    Step4:Compile switches to isolate the package in the C# file.

    #if NUGET_ENABLE 
    // Code
    #endif