1

I have an app which can come in one of 3 "flavors", the flavor depends only on the NuGet packages that are referenced in the project. In order to simplify the build, I want to use a custom property to define the flavor and then use conditions on the package references. It should be possible to build the app using Visual Studio or using MSBuild CommandLine. I added this to the PropertyGroup:

<Flavor Condition= "'$(Flavor)'==''">Flavor1</Flavor>

I can see the custom property is being set correctly, simply the conditions are being ignored This is what I tried:

  1. Setting the condition on the PackageReference itself as described here: https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference-condition
  2. Placing the conditioned packages in separate ItemGroup and setting the condition there
  3. Same as #2 but with Choose+When

Only #3 works and only in Visual Studio I need a solution that will work in both Visual Studio and MSBuild command line

#1 looks like this:

<PackageReference Include="Falvor1Package" Condition="'$(Flavor)'=='Flavor1'">
    <Version>1.1.1.1</Version>
</PackageReference>
<PackageReference Include="Falvor2Package" Condition="'$(Flavor)'=='Flavor2'">
    <Version>1.1.1.1</Version>
</PackageReference>

#2 looks like this:

<ItemGroup Condition="'$(Flavor)'=='Flavor1'">
    <PackageReference Include="Falvor1Package">
        <Version>1.1.1.1</Version>
    </PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(Flavor)'=='Flavor2'">
    <PackageReference Include="Falvor2Package">
        <Version>1.1.1.1</Version>
    </PackageReference>
</ItemGroup>

#3 looks like this:

<Choose>
    <When Condition="'$(Flavor)'=='Flavor1'">
        <ItemGroup>
            <PackageReference Include="Falvor1Package">
                <Version>1.1.1.1</Version>
            </PackageReference>
        </ItemGroup>
    </When>
</Choose>
<Choose>
    <When Condition="'$(Flavor)'=='Flavor2'">
        <ItemGroup>
            <PackageReference Include="Falvor2Package">
                <Version>1.1.1.1</Version>
            </PackageReference>
        </ItemGroup>
    </When>
</Choose>

I am using VS2019 and MSBuild 16 What am I missing?

Mr Qian
  • 21,064
  • 1
  • 31
  • 41
Mickey Cohen
  • 997
  • 7
  • 23

3 Answers3

1

AFAIK, that doesn't work. You cannot use arbitrary conditions (properties) on PackageReference. Also see this:

You can use a condition to control whether a package is included, where conditions can use any MSBuild variable or a variable defined in the targets or props file. However, at presently, only the TargetFramework variable is supported.

In other words, you could do something like this, but not use your custom property:

<ItemGroup>
    <PackageReference Include="..." Version="..." Condition="'$(TargetFramework)' == '...'" />
</ItemGroup>

Where the value of TargetFramework must be a valid TFM.

The same applies when adding the condition to the/a enclosing ItemGroup element.

Guesswork: I guess that the reason is, that when supporting arbitrary conditions here that wouldn't play well with Visual Studio. Because in the end, it has know which nuget packages (assemblies in the end), are referenced. The TargetFramework value is changed by changing the respective setting inside Visual Studio, so it can cope with that (manually), adjusting the referenced packages accordingly. It would be hard to do that for arbitrary stuff. But that all is just a guess and might be totally wrong.

Christian.K
  • 47,778
  • 10
  • 99
  • 143
  • The link you gave is the same as in my question. According to this article, #1 and #2 are supported and should work, but I am using a custom property. Maybe that is the problem? Using Choose+When works well is Visual Studio, I wonder why it doesn't work when using the command line... – Mickey Cohen Jan 26 '21 at 15:34
  • Oh sorry about the link. But especially see this part "only the _TargetFramework_ variable is supported.". That means that every other variable (including your `Flavor`) is not supported. At least that is how I read it. YMMV. – Christian.K Jan 27 '21 at 11:08
  • Thank, I guess I somehow missed that line :) So the trick is to find a way to use When<>Choose for msbuild to work. Cheers! – Mickey Cohen Jan 29 '21 at 09:30
1

I think it is an issue on VS IDE nuget Restore. And the issue is for the PackageReference nuget management format of the non-sdk net framework project. However, the issue is not for new-sdk project.

I have tested the issue multiple times and the condition will be ignored by VS IDE nuget restore. And it is an issue no doubt.

So I suggest you could report the issue to the Team.

I have raised the issue on Github.

However, nuget restore and msbuild restore can specify the condition on non-sdk project. So the issue is a difference between msbuild restore, nuget restore and VS IDE Restore.

So as a suggestion, you could do some changes on the project of VS2019:

Right-click on the Project Properties-->Build Event--> add this on the Pre-build event command line:

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" -t:restore $(ProjectDir)

And then you can build your project on VS2019 without any problems.

Mr Qian
  • 21,064
  • 1
  • 31
  • 41
  • 1
    Thanks, but as https://stackoverflow.com/users/21567/christian-k pointed out, the condition on package reference can only be used for targetframework. I will try different ways with Choose<>When as it uses the condition on an upper level and might solve the problem – Mickey Cohen Jan 29 '21 at 09:34
0

This is how I accomplish it:

<Choose>
    <When Condition=" '$(Configuration)'=='Release' ">
        <ItemGroup>
            <PackageReference Include="Volo.Abp.Autofac" Version="7.3.2" />
            <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="7.3.2" />
        </ItemGroup>
    </When>
    <When Condition=" '$(Configuration)'=='Debug' ">
        <ItemGroup>
            <ProjectReference Include="..\..\abp\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
            <ProjectReference Include="..\..\abp\framework\src\Volo.Abp.Caching.StackExchangeRedis\Volo.Abp.Caching.StackExchangeRedis.csproj" />
        </ItemGroup>
    </When>
</Choose>
Doug Wilson
  • 4,185
  • 3
  • 30
  • 35