Определение символа препроцессора C # на основе NuGet PackageReference

#.net-core #msbuild #csproj #preprocessor-directive

#.net-core #msbuild #csproj #директива препроцессора

Вопрос:

Я хотел бы определить символ NEWTONSOFT , если (и только если) Newtonsoft.Пакет Json NuGet добавляется как PackageReference в мое приложение .NET Core. Как я могу это сделать?

РЕДАКТИРОВАТЬ: чтобы уточнить, я хотел бы добавить символ, если ссылка присутствует. И если я удалю ссылку, символ больше не должен определяться, но я не должен вручную добавлять / удалять определение символа. Что-то вроде этого:

 <Choose>
    <When Condition=" '$(PackageReference).Identity'=='Newtonsoft.Json' ">
        <PropertyGroup>
            <DefineConstants>HDN</DefineConstants>
        </PropertyGroup>
    </When>
</Choose>
  

За исключением того, что это не работает.

Ответ №1:

Способ сделать это автоматически — включить цель, которая вносит логику сборки в ваш файл csproj следующим образом:

 <Target Name="AddPackageSpecificConstants" BeforeTargets="BeforeCompile">
  <PropertyGroup>
    <DefineConstants Condition="@(Reference->AnyHaveMetadataValue('NuGetPackageId','Newtonsoft.Json'))">$(DefineConstants);NEWTONSOFT_JSON</DefineConstants>
    <DefineConstants Condition="@(Reference->AnyHaveMetadataValue('NuGetPackageId','YamlDotNet '))">$(DefineConstants);YAML_DOT_NET</DefineConstants>
  </PropertyGroup>
</Target>
  

Подключаясь к процессу сборки, это может определить, есть ли в вашем коде какие-либо ссылки во время компиляции (что означает, что поверхность API pacakges доступна в вашем коде C #) на конкретные пакеты NuGet, даже если на них есть только транзитивные ссылки (например, вы ссылаетесь на библиотеку, которая ссылается на Newtonsoft.Json, чтобы вы могли его использовать).

При выполнении таких определений, как <X>$(X);</X> дополнительные константы, к свойству добавляются, так что это оставляет нетронутым все, что SDK предоставляет вам по умолчанию на основе целевой среды или другого содержимого вашего проекта.

Комментарии:

1. Извините за задержку, отличный ответ!

Ответ №2:

Вы можете добавить свою Conditional compilation symbols Debug вкладку Project Properties и использовать директивы препроцессора Roslyn следующим образом :

 #if NEWTONSOFT amp;amp; !JSON.NET
// Your Codes
#endif
  

Условные символы компиляции

Согласно документам Microsoft, у вас нет никакой директивы препроцессора для Nuget пакетов.

Комментарии:

1. Да, извините, я должен был быть более ясным. Я хотел бы добавить их «автоматически», когда присутствует PackageReference.

2. Как я знаю, для «автоматического» не существует Preprocessor Directive Nuget Packages .

3. Но я должен упомянуть некоторые варианты с Cake.Recipe . (например, директивы надстройки). cakebuild.net/docs/fundamentals/preprocessor-directives