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?
Related
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.
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.
In my solution I have a top level project with a bunch of dependent projects. One of the dependent projects has a required reference to the Nest nuget package. So in our nuget package config for the solution, I have Nest installed only on the project that references it.
The top level project has a reference to this dependent project, but no references to the Nest namespace. It builds without warnings or errors, however, in runtime, I have an issue saying
Could not load file or assembly 'Nest, Version=7.0.0.0, Culture=neutral, PublicKeyToken=96c599bbe3e70f5d' or one of its dependencies. The system cannot find the file specified.
When I manually install the Nest package on my top level project, it succeeds without issue.
Why does this occur? Shouldn't installing the Nest package on the dependent project resolve this dependency?
One of the dependent projects has a required reference to the Nest
nuget package.
Did you call Nest's function in the dependent project? VS will not copy the dependent project's assembly into top-level project if it finds the dependent project doesn't actually call(need) the assembly in code.
Why does this occur? Shouldn't installing the Nest package on the
dependent project resolve this dependency?
I'm not sure the cause of the issue with info available in your question, many factors can cause the strange behavior and sometimes VS version would also affect it...
Assuming you have a top-level project A and it depends on project B using Project Reference.
1.If both them targets .net framework, please make sure they use the same way to manager nuget packages.(Both using packages.config or both using PackageReference)
2.If A is .net framework project while B is .net standard project, please make sure the A is also using PackageReference format to manage nuget packages.
Cause .net standard(new SDK format) uses PackageReference packages, if A uses Packages.config and reference B, the build system will be confused about the different nuget formats in the build process. And we won't find the Nest.dll copied from B's output folder to A's output folder.
For this situation, try adding <RestoreProjectStyle>PackageReference</RestoreProjectStyle> into top-level A's project file.(xx.csproj) It will make sure both A and B can be restored as PackageReference style.
3.If A is .net framework with packageReference, and B is .net framework with Packages.config, right-click the packages.config and choose Migrate Package.config to PackageReference button. Also you may get some help from this document.
4.If your top-level project is .net core and B project targets .net standard, in VS2017, the nest.dll won't be copied into A's output folder, you can try adding <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to your A.csproj to resolve this issue. Similar issue see here. (And VS2019 16.3.8 has fixed this issue, this issue mostly occurs in VS2017)
And this behavior is also affected by VS version, if you're using VS2017, please update it to latest 15.9.17 for better experience. If you're using VS2019, please update it to 16.3.8.
Hope it helps :)
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.
One of the nuget packages that I am using have a minor problem that I have solved with a pull request. I would however want to include the fix in the build of my own application and I do not want to wait until the fix is released as part of a new version of the nuget package. Which procedure should I now follow to achieve this?
Can I keep my package reference and override the assembly provided by nuget with my own custom version of the assembly? I have tried to just copy the custom assembly to the corresponding location in nuget packages folder but it does not work.
Do I have to remove the nuget package reference and keep the custom library in my version control until the fix gets released?
Especiall when you're working with a team or using a build server, you'll want to not do an in-place replace of the same package version.
You can either add a direct reference to the custom-built assembly (and be sure to version it or to include the source in source control so your colleagues or the build server can compile it themselves), or create a new NuGet package with a higher version number and upgrade to that version.
If you don't have a private NuGet server, you can simply add a (shared) directory as package source for your custom built package, as explained in How to install a Nuget Package .nupkg file locally?.
It may work with the same package version, but then you'll have to remove and reinstall it, and make sure it isn't cached anywhere so the old package won't simply be added again. So you better just change the version number.