Define a C# preprocessor symbol based on NuGet PackageReference - .net-core

I'd like to make define a symbol NEWTONSOFT if (and only if) the Newtonsoft.Json NuGet package is added as a PackageReference to my .NET Core app. How can I do that?
EDIT: To clarify, I'd like add the symbol, if the reference is present. And if I delete the reference, the symbol should no longer be defined - but I should not manually add/remove the symbol definition. Something like this:
<Choose>
<When Condition=" '$(PackageReference).Identity'=='Newtonsoft.Json' ">
<PropertyGroup>
<DefineConstants>HDN</DefineConstants>
</PropertyGroup>
</When>
</Choose>
Except this does not work.

A way to do this sort of automatically is including a target that contributes build logic into your csproj file like this:
<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>
By hooking into the build process this can detect if your code has any compile-time references (meaning the API surface of the pacakges is available in your C# code) to specific NuGet packages, even if they are only transitively referenced (e.g. you reference a library that references Newtonsoft.Json so your could can use it).
By doing definitions like <X>$(X);</X> the additional constants are added to the property so this leavs intact anything the SDK gives you by default based on the target framework or your other project contents.

You can add your Conditional compilation symbols in Debug tab of Project Properties and use Roslyn Preprocessor directives like this :
#if NEWTONSOFT && !JSON.NET
// Your Codes
#endif
Based on Microsoft Docs, You have not any preprocessor directive for Nuget packages.

Related

How to Exclude Compiled .cshtml (.g.cs) from Build

While designing a dotnet new template, I've been trying to exclude certain files depending on the build configuration for a MVC web app (ASP.NET Core MVC). This is straightforward to do via \.template.config\template.json, but I want to be able to test different permutations of the template by setting preprocessor directives and excluding certain files from compilation.
For example, if a developer doesn't require identity in their project, certain identity-related files would be excluded as follows via the .csproj file:
<ItemGroup Condition="'$(Configuration)|$(Platform)'!='RequiresIdentity|AnyCPU'">
<Compile Remove="**/Areas/Identity/**/*" />
<Compile Remove="**/Views/Admin/**/*" />
</ItemGroup>
I'm confident this is removing the files that are not required when the build config is anything other than RequiresIdentity, but it appears that the .cshtml is precompiled before the source files are removed by the configuration above. This results in many errors of the form shown below, generated by *_cshtml.g.cs files:
CS0246 The type or namespace name 'prop' could not be found (are you missing a using directive or an assembly reference?)
Has anyone ran into this problem before and know of any potential workarounds?

Define C# preprocessor symbol in NuGet package

Can a NuGet package define a preprocessor symbol for the consuming project? And if so, how?
If your package (My.ExamplePackage) contains an MSBuild file named like the package name + .targets in the build directory (so build\MyExamplePackage.targets), you can use it to amend the DefineConstants property that may have been set to defaults or reset in the project:
<Project>
<PropertyGroup>
<DefineConstants>$(DefineConstants);MY_PREPOCESSOR_SYMBOL</DefineConstants>
</PropertyGroup>
</Project>
While the package can contain both a .props and .targets file, the .targets file will be imported after the main body of the csproj file being built so if it the project re-sets DefineConstants (meaning not adding to it by prepending $(DefineConstant);), the .targtes file has a chance of adding to this property.

Including Unmanaged DLL in NuGet Package Using csproj

I'm developing a .NET Core 2.1 library that depends on an unmanaged DLL. I'd like to include the unmanaged DLL in the NuGet package as well. The problem that I am running into is that if I try to specify all of the information in the .csproj file, the dotnet build process throws the following warning:
warning NU5100: The assembly 'content\lib\subdir\somedll.dll' is not
inside the 'lib' folder and hence it won't be added as a reference
when the package is installed into a project. Move it into the
'lib' folder if it needs to be referenced.
I know that I can embed the unmanaged DLLs by writing a .nuspec (in fact, I have). However, it seems like I shouldn't need to write one with the latest .csproj file format.
Question: How can I use the .csproj file to embed unmanaged DLLs in a NuGet package?
Specifying <ItemGroup><None> in the .csproj file seems to include the files in the output directory but they do not make it into the NuGet package.
Specifying <ItemGroup><Content> in t he .csproj file will get them added to the NuGet package but in the Content directory instead of in the Lib directory.
If I really have to have both a .csproj file and a .nuspec file, what is the best practice for where to put the metadata? In t he .csproj file? In the .nuspec file? Maintain and sync both? Is there a something in the tool chain that can do this for me?
I'm working in Visual Studio Code V1.24, and .NET Core/dotnet V2.1.
You need to specify explicit package path metadata on the element so that the dll/so/dylib file ends up at the right place in the package so that it is recognised as runtime-specific native DLL:
<ItemGroup>
<None Include="unmanaged.dll" Pack="true" PackagePath="runtimes\win-x64\native" />
</ItemGroup>

Where to specify --module flag in VS 2015?

I am using typescript 1.5 and VS 2015 RC with new ASP.NET 5 Project templates.
Typescript compiles fine however I am getting the following error on my exported classes:
cannot compile external modules unless the "-module" flag is provided
I want to silence this error however I am unable to specify any typescript options though VS 2015. I also tried tsconfig.json file however it seems it is not effective to just add this file. Perhaps there is an additional step I am missing. What can I do ?
Typically this setting is in the project properties on the TypeScript build tab in the project properties (for your current build configuration such as Debug or Release).
Since you are saying that the TypeScript build tab doesn't appear, you may not have a valid reference to the TypeScript "props" file in your project. Look for a line like this in your .csproj or similar file:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props')" />
If it doesn't exist, add it to your project and then fix up the path to be correct for your install of Visual Studio and TypeScript (just search for the "Microsoft.TypeScript.Default.props" file on your hard drive). When you reload the project, the TypeScript build properties tab should appear.
The other thing you need is a reference to the TypeScript "targets" file such as this:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets')" />
Note that a targets reference generally has to be as low as possible in your project - possibly even just before the </Project> tag.
Initialization of TypeScript in Visual Studio is dependent on the .props and .targets files existing so that could also be the issue.

Specifying a flex-config.xml with Maven / Flex Mojos

I have to port an existing project to Maven, and it includes a resource called "config.xml" that is copied to the deploy directory alongside the SWF and HTML, and loaded at run-time to locate a bunch of WSDLs.
Flex Mojos has taken it upon itself to assume that my xml file is a flex-config file with instructions for the compiler, which of course promptly gives up the ghost.
The question is: How do I specify a named config file for the compiler so that Maven stops this nonsense (as well as specifying my compile-time options)?
<configuration>
<configFile>path/to/yourConfigFile.xml</configFile>
</configuration>
https://docs.sonatype.org/display/FLEXMOJOS/compile-swf-mojo.html#compile-swf-mojo.html-configFile
Sorry for the archeology. If you want to hide only some warnings, you can add the following in your pom:
<configuration>
<!-- Maven is more strict than Flash Builder, so I'm hiding some warnings -->
<compilerWarnings>
<warn-no-constructor>false</warn-no-constructor>
</compilerWarnings>
</configuration>
From this documentation:
compilerWarnings
A list of warnings that should be enabled/disabled
Equivalent to -compiler.show-actionscript-warnings,
-compiler.show-binding-warnings,
-compiler.show-shadowed-device-font-warnings,
-compiler.show-unused-type-selector-warnings and -compiler.warn-*
Usage:
<compilerWarnings>
<show-actionscript-warnings>true</show-actionscript-warnings>
<warn-bad-nan-comparison>false</warn-bad-nan-comparison>
</compilerWarnings>

Resources