6

I am trying to add a project and file reference to the same dll in the csproj with the BuildingInVsideisualStudio property. But when they are in the csproj together, only the file reference is picked up. If I remove the file reference, it picks up the csproj. I have tried swapping the order, but no luck. Any ideas why this doesn't work?

Here is the basic idea:

<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == false">
    <Reference Include="MyNamespace.Mine">
        <HintPath>..\$(OutDir)\MyNamespace.Mine.dll</HintPath>
    </Reference>
</ItemGroup>
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == '' Or '$(BuildingInsideVisualStudio)' == true">
    <ProjectReference Include="..\MyNamespace.Mine.csproj">
        <Project>{GUID}</Project>
        <Name>MyNamespace.Mine</Name>
    </ProjectReference>
</ItemGroup>

Someone else has gone down this path, too, but it appears there are some caveats. I need to do this conditional because of my build process, which cannot change. Using the file reference forces me to lose the Go to Definition and Find All References (sorry, but I cannot install ReSharper to solve this either).

Community
  • 1
  • 1
kevindaub
  • 3,293
  • 6
  • 35
  • 46

4 Answers4

8

Two problems I see:

  1. You didn't take into account that $(BuildingInsideVisualStudio) can be empty (''). For the first condition use:

    <ItemGroup Condition="'$(BuildingInsideVisualStudio)' != 'true'">

  2. Always surround both operands with single quotes:

    <ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">


MSDN reference:

Single quotes are not required for simple alphanumeric strings or boolean values. However, single quotes are required for empty values.


UPDATE:

May be a long shot, but you can try using conditions on the property defintions:

<PropertyGroup Condition="'$(BuildingInsideVisualStudio)' != 'true'"><!-- In CMD -->
    <ReferenceInclude>MyNamespace.Mine"</ReferenceInclude>
    <ReferenceIncludePath>..\$(OutDir)\MyNamespace.Mine.dll</ReferenceIncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'"><!-- In VS -->
    <ProjectReferenceInclude>..\MyNamespace.Mine.csproj</ProjectReferenceInclude>
    <ProjectReferenceIncludeId>{GUID}</ProjectReferenceIncludeId>
</PropertyGroup> 

So the references will get resolved conditionally:

<ItemGroup>
    <Reference Include="$(ReferenceInclude)">
        <HintPath>$(ReferenceIncludePath)</HintPath>
    </Reference>
</ItemGroup>
<ItemGroup>
    <ProjectReference Include="$(ProjectReferenceInclude)">
        <Project>$(ProjectReferenceIncludeId)</Project>
        <Name>%(ProjectReferenceInclude.MSBuildProjectName)</Name>
    </ProjectReference>
</ItemGroup>
KMoraz
  • 14,004
  • 3
  • 49
  • 82
2

In Visual Studio 2010 and 2012 you can also use a Choose statement instead of adding a reference with a condition. This seems to work a lot better:

<Choose>
  <When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
    <ItemGroup>
      <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
    </ItemGroup>
  </When>
  <Otherwise>
    <ItemGroup>
      <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
    </ItemGroup>
  </Otherwise>
</Choose>
jessehouwing
  • 106,458
  • 22
  • 256
  • 341
  • Adding difference references isn't the issue. Adding project reference or a dll reference is the issue, but I will give this a try. – kevindaub Aug 23 '12 at 22:22
  • 1
    We're using it internally now, and for us it's working just fine. We're using the `$(BuildingInsideVisualStudio)` and the `$(TeamBuildConstants)` variables to direct based on the fact whether we're building in Visual Studio, Team Build or 'Otherwise' (command line, or anything else) – jessehouwing Oct 02 '12 at 13:09
  • Did you try it? Cause it will actually list your reference just once. – jessehouwing Dec 14 '12 at 00:06
  • 1
    Yes, it did work, but I only have Visual Studio 2012 at home. Unfortunately, I later realized that our build system is "insane" and actually fails because it rewrites the csproj. During this process, it removes the choose, when, and otherwise; thus, I am left with 2 references no matter what. But your solution did work (at least in 2012). – kevindaub Dec 15 '12 at 04:45
  • This is the only solution that works with Visual Studio Online I think. Thanks! – Kerem Demirer Nov 09 '16 at 00:07
1

Assuming I understood the question correctly after bit of experimentation it seems that naming them differently would solve most of the problems; msbuild would respect the condition and use assembly reference, VS would display them both in solution explorer but would prebuilt the reference as if it is project kind and would keep goto-definition without R# working. Conditional import is something else worth looking into but I haven't tried it.

<ItemGroup>
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" Condition="'$(Foo)'=='Bar1'">
        <Project>{FD0E01BC-7777-4620-9EF2-5F60804B3173}</Project>
        <Name>ClassLibrary1-ProjRef</Name>
    </ProjectReference>
    <Reference Include="ClassLibrary1" Condition="'$(Foo)'=='Bar2'">
        <Name>ClassLibrary1-AssRef</Name>
        <HintPath>..\ClassLibrary1\bin\Debug\ClassLibrary1.dll</HintPath>
    </Reference>
</ItemGroup>
Ilya Kozhevnikov
  • 10,242
  • 4
  • 40
  • 70
0

The response Microsoft posted to this question on Connect indicates that Visual Studio deliberately ignores conditions on assembly references, project or not. This is understandable; however, the resolution process seems to always prefer file-based references when the project file contains more than one reference to the same assembly, which is moot.

In short, you're out of luck, unless there is a way to tell VS to consider a project reference even with a file reference is present to the same assembly. I do not know of a way to do this, and I'd also be interested to learn if it's still possible somehow.

Alan
  • 6,501
  • 1
  • 28
  • 24
  • Although I still believe it's a bug in VS/MSBuild, I was able to workaround it by changing the project name. I don't think I can split the bounty. – kevindaub Jun 06 '12 at 15:15