Nuget package manager installs dependencies for another target - c#

So I have a DLL which is targeting multiple versions (.net 4.5, 4.6.1, netcore 2.0) which is pushed to a Klonkdike
Now I want to use this DLL, my project is .net 4.6.1, so I expect to resolve dependencies on this target only.
However my packages.config gets all .netcore dependencies. How can I prevent that?
This is the DLL:
And this is what is added when fetch this package:
I would expect to have only UAParser to be added and no other change since I already have the dependencies.
There are 3 folders in the lib folders of the package, so I would expect to only need these specific dependencies...
How can I avoid add all these dependencies?

UAParser is a pure .NET Standard based library.
.NET Standard versions lower than 2.0 depend on these libraries. However, the new tooling in VS 2017 (make sure you have at least 15.5.0) trims out these packages during build and makes sure the right assemblies are in place (these may also be System.* dll files but are not coming from these packages).
These dlls put in place by tooling are needed to implement the .NET Standard contract on .NET Framework - they forward to .NET Framework implementations.
In the upcoming .NET 4.7.2, the plan is to no longer need any of these DLLs. Until then, they are necessary.

Related

Azure Function can't find a file/dll that it suppose to use

I have an azure webjob that used to work well. When I added an internal nuget of the company I work for and used it, I received the following error:
Could not load file or assembly 'System.Threading.Tasks.Dataflow, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
The weird thing is that both the interal nuget, and a nuget that was defualtly existed in that project before, are using the System.Threading.Tasks.Dataflow, Version=5.0.0.0
When .NET was first created, the Windows-only .NET Framework, it has a concept called "strong naming" which makes the assembly version part of the assembly identity (not just the name, but also includes public key). With the .NET Framework when A.dll has a reference to B.dll, at runtime the version of B.dll must match the version A.dll was compiled against. The way to work around that was to use a binding redirect in an app.config or web.config file.
With .NET Core, they stopped enforcing this, but they still put in a check to make sure that the assembly found on disk is a HIGHER version than what the compile time reference was.
This is relevant because you're using Microsoft.NET.Sdk.Functions version 3.0.13, which targets .NET 3.1. Therefore, I assume you're Azure Functions app is running on .NET Core 3.1. I don't know what the assembly version of System.Threading.Tasks.Dataflow that ships in the .NET 3.1 runtime is, but I'd expect it to be version 3.something.
While NuGet package versions do not have to match assembly versions, it is very often the case that the major (and sometimes minor) versions do match, especially for System.* packages/assemblies.
Putting 2+2 together, you're running on .NET Core 3.1, which has System.Threading.Tasks.Dataflow.dll version 3.something, but your something.Kafka.dll assembly is compiled against System.Threading.Tasks.Dataflow.dll version 5.something. Since the compile time reference is a higher version of the version available at runtime, the .NET assembly loader refuses to use it.
There are two actionable things now.
Firstly, you can do one of three things to fix your project. Use a newer version of Azure Functions that targets .NET 5 or higher. Alternatively, use an older version of your whatever.Kafka package that doesn't depend on BCL (base class library) assemblies that are higher version than the .NET Core 3.1 runtime provides. Finally, I'm guessing the reason the dll doesn't exist in your project's bin directory is because of this issue: https://github.com/Azure/azure-functions-host/issues/5894
Secondly, contact the package owners of this Kafka package, and inform them that they don't need to use the Dataflow NuGet package. .NET Core 1.0 had it built into the BCL, so the package is only needed for .NET Standard and .NET Framework projects. If this Kafka package does support .NET Framework or .NET Standard, then if they change their PackageReference to include Condition=" '$(TargetFrameworkIdentifier) != '.NETCoreApp' ", then the package will be used only in .NET Framework and .NET Standard, and the BCL version of the package will be used for .NET Core and .NET 5 and above. If they use any other System.* package (that ships in the runtime), they should do the same. Of course, if the package owner refuses to remove Dataflow as a package dependency, or if there are other packages that bring in Dataflow as a transitive package, then you're stuck. But by informing the Kafka package owners of this, they at least have the opportunity to improve their package.

Adding .NET Core Multi-target to a .NET Framework library

I have a .NET Framework library with NuGet package dependencies. This library is consumed exclusively by .NET Framework projects. Some of them by local project references, and most through NuGet. I publish the library to a private NuGet server.
A few projects have cropped up using .NET Core based infrastructure, and I would like to make my standard library available to these projects. I am not switching any of the existing infrastructure to .NET Core. I don't want to introduce .NET Core dependencies into every existing .NET Framework project. I have noticed that when I install certain multi-targeted libraries, sometimes they include "netstandard" or something like that -- and install lots of dependencies. These are unacceptable and get immediately uninstalled from .NET Framework projects.
Is it possible to multi-target my .NET Framework (4.72 if it matters) project to .NET Core as well, while still producing native .NET Framework libraries? I can copy and paste all the code in my library into a netcoreapp3.1 project, install NuGet dependencies, and that code runs fine. However, I don't want to port this library to .NET Core, and then multi-target it back to .NET Framework. As far as I am aware, that is not the same as having a native implementation. I just want to be able to use the library in a .NET Core app without copying and pasting the entire library, and letting the versions get out of sync. The less ceremony the better.
My csproj file doesn't have a <TargetFramework or <TargetFrameworks> property. It has a <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> property.
Is what I'm trying to do possible? I can't tell from the documentation I have read.

Specifying Nuget Package Platform Target

I want to create a Nuget Package for a C# library that targets .NET Framework 4.0 and higher.
If I put my library in a directory named Net40, will this cause issues for projects that target say 4.1 and higher?
Should i just publish my library in a lib folder without specifying the supported .NET Framework version?
My library supports .NET Framework 4.0 and higher.
The reason why I am asking is that sometimes projects get messed up quickly when they target a different platform whilst the installed libraries via NuGet target another platform version. At least I want to avoid issues when developers target 4.0 and higher.
I hope your advice will be very helpful.

Extra files in the project (NPGSQL)

The question is stupid enough, but it didn’t work with NuGet before. After installing the NuGet package through the console, to connect to PostgreSQL, files appeared that NetFramework should contain. Without copying these files, the project does not start. What to do to get rid of them and not copy them to the directory with the program. In my understanding, these files should be taken from the framework.
See screenshots:
All need files in project C#
My guess is that you have .Net Standard 2.0 libraries/dependencies in your project.
.NET 4.6.1 might add additional runtime dependencies in your output folder:
.NET 4.6.1, 4.6.2, .NET 4.7 and 4.7.1 all have partial .NET Standard
2.0 support in the natively shipped runtimes, but they still are .NET Standard 2.0 compliant by adding additional runtime dependencies into
your output folder to provide the missing functionality. NuGet along
with the runtime targeting handles automatically adding those
dependencies to your projects to provide the needed runtime support
for those extra features. A lot of those assemblies override behavior
from the base framework and .NET uses runtime redirects to route api
calls to the appropriate assemblies rather than than mscorlib.dll or
other system assemblies.
.NET 4.7.2 is the first version of the full .NET Framework that is
fully .NET Standard 2.0 compliant without any additional dependencies.
See: https://weblog.west-wind.com/posts/2019/Feb/19/Using-NET-Standard-with-Full-Framework-NET
In other words, targeting .NET 4.7.2 should get rid of the additional files.

Release multiple assemblies in single .net core package

I'm trying to release my library (lz4net) for .NET Core. The library "architecture" differs a little from "normal" as it contains multiple assemblies but only one should be referenced, the other ones are just its dependencies. They are not separate packages though.
So, assembly LZ4.dll should be referenced by the application, while LZ4pn.dll should not, it just should be there as LZ4.dll (main one) may use it. `LZ4pn.dll" is not usable on its own therefore it is not released as separate package.
It seems to be working fine in: net2, net4, and pcl, but it netcore does not "see" LZ4pn.dll if it is not referenced by application.
NOTE: I've checked and C:\Users\xxx\nuget\packages\lz4net\1.0.11.93\lib\netstandard1.6 (after installation of .nupkg) do contain both assemblies.
So, LZ4pn.net is not in <references> section as it should not be referenced by application directly. It is not in <dependencies> section as it is not external dependency which needs to be separately downloaded. It is just there - in netstandard1.6 subfolder of nuget package. .NET Framework (2+) work fine but .NET Core does not discover this assembly.
Any help?
Maybe you know some open-source package which uses the same approach (multi-assembly packages which reference only top assembly)?

Categories