Nuget with Build configurations - c#

I'm moving over a project to make it into a nuget package. The project has preprocessor directives in it to check which custom build configuration the developer is in. If they are in Build config A then it pulls A service settings, if they are in B, then it pulls B's settings. The problem is when I package this service up and the nuget package is being used in a separate process with the same build configuration it doesn't respect the devs build configuration choice because the nuget has been compiled with whatever setting it was built in. We have set it up into 3 dlls in a single nuget package.
Is there a way to choose which nuget dll it uses based on the custom build configuration without modifying the csproj code?

Is there a way to choose which nuget dll it uses based on the custom build configuration without modifying the csproj code?
This is not supported as far as I am aware with the NuGet. You can only have one NuGet package with a specific build configurations in a single project's file. Moreover, NuGet now only supports multiple .NET framework versions, not supported multiple configurations.
You can have different NuGet packages if you have different build configurations. This project is specific use by library authors who have platform specific projects that need different NuGet packages.
Besides, It may be simpler to not use NuGet to add the assemblies to your project. Just use NuGet to pack the package with multiple dlls file, then directly reference the assemblies you need with conditions.

Related

PackageReference not copying dll to consumer (test) project output with ExcludeAssets = "runtime" and PrivateAssets = "none"

Simple setup here:
Project A - .NET 4.7.2 framework library project
PackageReference to SeriLog 2.9.0
ExcludeAssets="runtime",
PrivateAssets="none", this is optional because by default it should copy DLLs (setting = "runtime")
TestProject B - .NET 4.7.2 framework unit test project
Project A is added as ProjectReference
SeriLog DLL and all dependencies should be copied here
Output: The SeriLog DLL is not copied to the output folder of ProjectA but also not to TestProject B. TestProjectB should contain from my perspective the SeriLog.dll. Am I missing something? Or any other options to achieve that?
Remarks:
As far as I understood from the PackageReference format specification, I'm using the attributes correctly.
The ExcludeAssets attribute controls the assets for the project where it has been defined. PrivateAssets controls the flow to projects which are using the Project A.
From the docs you linked:
ExcludeAssets:
These assets will not be consumed
runtime:
Contents of the lib and runtimes folder and controls whether these assemblies will be copied out to the build output directory
so, ExcludeAssets="runtime" explcitly means "don't copy dlls". I'd suggest removing any usage of ExcludeAssets and PrivateAssets and let NuGet use its defaults. If you don't want NuGet's default behaviour, then start using these keywords.
However, there's another thing going on as well. You said your test project is a non-SDK style project. It's possible to target the .NET Framework from an SDK style project, but unfortunatly Visual Studio's templates call them ".NET Core" or '.NET Standard", so people incorrectly assume they can't target .NET Framework. Anyway, while packages are transitive for projects using PackageReference, SDK style projects are always PackageReference, even when there are no packages referenced. However, non-SDK style projects are not. You either need to have one PackageReference in the project or excplicitly set the MSBuild property RestoreProjectStyle to PackageReference. Otherwise NuGet will look for a packages.config file and if that's not found, NuGet considers the project to not use NuGet at all.
Although, it occurs to me now that your test project almost certainly contains references to packages, at least the test framework itself. If those references are via packages.config, this is a known incompatibility. packages.config projects that have project references to PackageReference projects do not completely work properly. There's better compatibility the other way around, or alternatively migrate the test project to PackageReference as well. Honestly I'd strongly suggest migrating all projects that you can to SDK style, even if you keep targeting the .NET Framework. It's the future of .NET and the tools work better. Fewer of these little gotchas.
If the test project is using PackageReference already, then the problem is just that the ExcludeAssets="runtime" is being applied transitively, and by removing it from your referenced project, it will automatically flow to the test project.

StyleCop.Analyzers Nuget Dependencies

I have created a Nuget package on a private Azure Artifacts environment, that houses a custom configuration for StyleCop.Analyzers so that the configuration for coding standards can be centralised. This all works absolutely fine and can be installed in other projects with no issue.
I have a separate class library which is being built into a Nuget package, and this project utilises my custom StyleCop package. This package also builds correctly, but in the list of dependencies is my custom StyleCop.Analyzers package. This means that everywhere the class library gets installed, the custom StyleCop.Analyzers package will be installed as well. I don't feel this is correct as it is purely a development-scoped package and should not be included as an actual dependency.
The class library does not feature a .nuspec file, everything is handled through the .csproj and some Azure Pipeline's wizardry. Is the dependency chain correct, or is there something that can be done to ensure that the custom StyleCop.Analyzers package is not listed as a dependency?
Turns out if you add <devDependency>true</devDependency> node to the .nuspec file then the dependency does not get shipped to packages that consume it.

Shipping msbuild task as nuget

I need your help.
I'm developing an msbuild task that performs certain actions upon msbuild.
I want my users to be able to download and install a nuget package and once the package is installed the build task will be part of the build process.
I know how to release a nuget package and i know how to includes a custom targets file together with the nuget, what i don't know is how to add the import statement to the csproj upon nuget installation:
Is there a way to do so or am i asking for too much?
Thanx!
Gilad
The docs aren't in the easiest to find place, but here's a link to the docs on including MSBuild props/targets files in your package.
Basically, you put the file in the package in the location build\<tfm>\<package_id>.props. For example build\netstandard2.0\MyPackage.props. If you want your build targets to be included in all TFMs, you can use build\<package_id>.props, but if your package also contains other assets like lib/ or contentFiles/, the "no-TFM" build files will cause "asset-target fallback" to fail, so if your package has only net472 libs, and the build files, a project targeting netcoreapp3.0 will get only the build assets, none of the net472 assets. If your build files are in a TFM folder, then NuGet's asset target fallback will select both the lib and build assets. So, I strongly encourage everyone to always use the TFM folder.
The docs need to be improved, but the table explaining lists build, buildTransitive, and buildMultiTargeting. Projects using packages.config only use build assets under build. Projects using PackageReference only use build and buildMultiTargeting assets when the project references the package directly. Assets under buildTransitive get selected when the package is pulled in transitively, rather than directly. The difference between build and buildMultiTargeting is complex. If you understand the concept of "inner-build" and "outer-build" in multi-targeting SDK style projects, that's the difference (build is inner-build), otherwise only use build.
I should update the docs to have this information.

Getting error attempting to publish a WPF which uses PackageReference

I'm working on upgrading one of our WPF applications. During my upgrade, I converted the application from using the packages.config format for NuGet packages to using the PackageReference format.
Everything seemed to work fine locally, but our build agent started complaining about our NuGet packages:
Error MSB3188: Assembly
'C:\Users\tfs\.nuget\packages\Utils\1.0.0\lib\net45\Utils.dll' must be
strong signed in order to be marked as a prerequisite.
This sort of makes sense because the Utils package is not referenced directly anymore. When you utilize the packages.config format, every NuGet package is referenced by the project, but when you utilize the PackageReference format, only the top-level packages are referenced; package dependencies are not included. Additionally, any projects which are referenced which have a NuGet dependency not explicitly referenced by the WPF project are also affected.
Adding the package dependencies directly to the WPF project solves this issue, but it seems like it shouldn't have to be done that way.
What's strange is when I go into the publish settings / application files for the project, the assemblies are not listed as Prerequisite, but they are marked as Install (Auto) instead.
Short of adding the NuGet package dependencies (not simply the top-level packages), what are my options here? Is there some sort of setting or msbuild parameter, etc. which I can use that allows me to use the PackageReference format while still only referencing the top-level packages?

Is there a way to have a C# solution use project references when local and nuget packages during TFS builds?

We've got two sets of projects, one is framework projects and the other is the actual app. The app references the framework projects directly via the visual studio project reference feature. The framework build process publishes a nuget package already. Is there any way to make it so when I trigger a build on TFS of the actual app it uses that nuget package instead of the project reference? Ideally I'd like to have it still be a project reference when local, but if that's not possible that's alright.
I discovered you can use conditionals in the csproj files to determine which item group to use, and by making a custom build configuration I can specify which item group to use on TFS.

Categories

Resources