Visual Studio conditional project reference based on a constant

chinh nguyen van picture chinh nguyen van · May 15, 2013 · Viewed 13k times · Source

For user authorization, I only want to include a specific module for each user. So I configured Conditional Compilation like this

<DefineConstants>TRACE;DEBUG;SAMPLECONSTANT1</DefineConstants>

and edited the project file like this:

<ProjectReference Include="..\Solution1.Modules.Module1\Solution1.Modules.Module1.csproj" Condition="$(DefineConstants.Contains('SAMPLECONSTANT1'))">
  <Project>{4E378BD0-4FF8-4160-9331-1ECBFD2B6F30}</Project>
  <Name>Solution1.Modules.Module1</Name>
</ProjectReference>

For this case I want to add reference to project Module1 if DefineConstants contains SAMPLECONSTANT1; but no matter what I put in DefineConstants, the solution always loads the Module1 project. What did I do wrong here?

UPDATE: Actually my code is correct. Please see J0e3gan's answer. Visual Studio UI does not reflect conditional references within the References folder of a project. Therefore all references are visible in any given configuration or platform selection. The compiler and IntelliSense on the other hand are aware of conditional references, honoring the correct settings both with visual feedback and error notification during builds.

Answer

J0e3gan picture J0e3gan · May 15, 2013

I suspect the problem is that you are conditioning a project reference to Module1, not whether to include Module1 in the solution.

Including a project in a solution (and hence loading it with the solution) and a project referencing another project in a solution are two different things of course.

UPDATE:

If you truly want to condition a project reference, Joe Wrobel wrote a related blog post that should help. The key takeaway is to wrap the ItemGroup that contains the ProjectReference to condition in a Choose element - for example:

<Choose>
  <When Condition="$(DefineConstants.Contains('SAMPLECONSTANT1'))">
    <ItemGroup>
      <ProjectReference Include="..\Solution1.Modules.Module1\Solution1.Modules.Module1.csproj">
        <Project>{4E378BD0-4FF8-4160-9331-1ECBFD2B6F30}</Project>
        <Name>Solution1.Modules.Module1</Name>
      </ProjectReference>
      <!-- other ProjectReference elements -->
    </ItemGroup>
  </When>
  <Otherwise>
    <ItemGroup>
      <!-- other ProjectReference elements -->
    </ItemGroup>
  </Otherwise>
</Choose>

From my tests this evening, this works great to condition a project reference(s) on whether a constant like SAMPLECONSTANT1 is defined. However, note that conditioned project references do not show in Solution Explorer under the (would-be) referencing project's References folder - regardless whether the conditioning constant is defined.

To see that the conditioning worked, I had to build: with SAMPLECONSTANT1 defined, the referencing project built successfully while using a class defined in Module1 - as expected; and without SAMPLECONSTANT1 defined, the referencing project failed to build because the class defined in Module1 could not be resolved - also as expected.