Условная ссылка на проект Visual Studio на основе константы

Для авторизации пользователя я хочу включить только определенный модуль для каждого пользователя. Итак, я настроил условную компиляцию следующим образом.

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

и отредактировал файл проекта следующим образом:

<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>

В этом случае я хочу добавить ссылку на проект Module1, если DefineConstants содержит SAMPLECONSTANT1; но что бы я ни вставил в DefineConstants, решение всегда загружает проект Module1. Что я здесь сделал не так?

ОБНОВЛЕНИЕ: На самом деле мой код правильный. Пожалуйста, смотрите ответ J0e3gan. Пользовательский интерфейс Visual Studio не отражает условные ссылки в папке References проекта. Поэтому все ссылки видны в любой заданной конфигурации или выбранной платформе. Компилятор и IntelliSense, с другой стороны, знают об условных ссылках, соблюдая правильные настройки как с визуальной обратной связью, так и с уведомлением об ошибках во время сборки.


person chinh nguyen van    schedule 15.05.2013    source источник
comment
Пожалуйста, не могли бы вы поподробнее, кажется, не очень много   -  person cuongle    schedule 15.05.2013
comment
Привет, Куонг Ле, я просто обновляю свой вопрос, для этого вопроса я хочу добавить ссылку на проект Module1, если DefineConstants содержит SAMPLECONSTANT1, но что бы я ни вставил в DefineConstants, решение всегда загружает проект Module1   -  person chinh nguyen van    schedule 15.05.2013
comment
Я думаю, что было бы лучше, если бы вы загружали модуль во время выполнения, а не во время компиляции. Для этого можно использовать отражение или MEF.   -  person cuongle    schedule 15.05.2013
comment
Я немного поработал над этим, основываясь на своем понимании того, что вы действительно пытаетесь обусловить ссылку на проект, а не включение проекта в решение: я нашел подход, который хорошо сработал для меня; и, надеюсь, вы обнаружите, что это хорошо работает для вас.   -  person J0e3gan    schedule 15.05.2013


Ответы (3)


Я подозреваю, что проблема в том, что вы определяете ссылку проекта на Module1, а не включать Module1 в решение.

Включение проекта в решение (и, следовательно, загрузка его вместе с решением) и проект, ссылающийся на другой проект в решении, — это, конечно, две разные вещи.

ОБНОВЛЕНИЕ:

Если вы действительно хотите обусловить ссылку проекта, Джо Вробель написал похожая запись в блоге, которая должна помочь. Ключевой вывод заключается в том, чтобы обернуть ItemGroup, который содержит условие ProjectReference to, в элемент Choose, например:

<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>

Из моих тестов этим вечером, это прекрасно работает, чтобы обусловить ссылку(и) проекта на то, определена ли константа, такая как SAMPLECONSTANT1. Однако обратите внимание на то, что ссылки на условные проекты не отображаются в обозревателе решений в папке ссылок проекта (предполагаемой) — независимо от того, константа определена.

Чтобы убедиться, что условие работает, мне пришлось построить: с определенным SAMPLECONSTANT1 ссылающийся проект успешно построен с использованием класса, определенного в Module1 - как и ожидалось; и без определения SAMPLECONSTANT1 связанный с ним проект не удалось построить, поскольку класс, определенный в Module1, не удалось разрешить, как и ожидалось.

person J0e3gan    schedule 15.05.2013
comment
Если я ссылаюсь на DLL, а не на проект, он работает нормально, например: <Reference Include="Solution1.Modules.Module1, Version=1.0.0.0, Culture=neutral, processorArchitecture=x86"> </Reference> Поэтому я не знаю, почему ProjectReference не работает. - person chinh nguyen van; 15.05.2013
comment
Ваш ответ правильный, я проверил, и это сработало, я только проверил папку «Ссылки» проекта и все еще вижу проект, поэтому я думаю, что мой код не работал, так глупо. Для всех, кому это интересно, вы также можете использовать мой код, он проще без использования тега Choose или When :) - person chinh nguyen van; 15.05.2013
comment
@chinhnguyenvan: Вы правы. Какая ирония: мне пришлось проработать подход Choose, чтобы обнаружить различие между ссылками и сборкой, а затем обнаружить (подсказанный вашим комментарием), что это имеет значение и для вашего подхода! поток MSBuild несколько обсуждает это. Теперь мне интересно, действительно ли Евгений Захареев имел в виду. Вы наверняка можете настроить ссылки, чтобы сделать их условными; дело в том, что он будет [ ][in] виден в VS и не редактируется через пользовательский интерфейс... в его ответе. - person J0e3gan; 15.05.2013
comment
@chinhnguyenvan: Интересно: поэтому я уловил разницу между вашими указаниями на то, что условная ссылка всегда была видна в разделе «Ссылки»… и моим опытом, что условная ссылка (и) всегда была невидимой. Используя атрибут Condition элемента ProjectReference, ссылка на условный проект всегда отображается в разделе «Ссылки», как вы описали; и используя подход Choose-When, который я изложил, ссылки на проект всегда _in_visible в разделе References. странный. :) Кстати, я проверил все с помощью Visual Studio 2010 Professional SP1 для полного контекста. - person J0e3gan; 15.05.2013
comment
ваше указание верно, оба наших кода работают, они просто видны в папке «Ссылки». Большое спасибо за вашу помощь. - person chinh nguyen van; 15.05.2013

Принятый ответ не сработал для меня. Однако я не утверждаю, что это неправильно. Что сработало для меня, так это:

<Import Project="..\MnM.GWS.Chip2\MnM.GWS.Chip1.projitems" Label="Shared" Condition="$(DefineConstants.Contains('Chip1'))" />
<Import Project="..\MnM.GWS.Chip2\MnM.GWS.Chip2.projitems" Label="Shared" Condition="$(DefineConstants.Contains('Chip2'))" />

Я не получил никакой ошибки при изменении констант.

person Mukesh Adhvaryu    schedule 23.11.2019

Если вы хотите использовать константу DEBUG, убедитесь, что она включена в свойствах вашего проекта (Properteis › Build › Define DEBUG Constant).

Образец на основе принятого ответа:

  <Choose>
    <When Condition="$(DefineConstants.Contains('DEBUG'))">
      <ItemGroup>
        <ProjectReference Include="..\..\..\..\..\MyLocalProjectPath.csproj" />
      </ItemGroup>
    </When>
    <Otherwise>
      <ItemGroup>
        <PackageReference Include="MyNugetPackage" Version="2.1.4" />
      </ItemGroup>
    </Otherwise>
  </Choose>
person Benni    schedule 17.03.2021