Using two different versions of same the NuGet package - c#

I wanted to use two different version same library (OpenCVSharp 2.x and OpenCVSharp 3.x).
I downloaded those two packages both to the separate project (let's call it OCV2Wrapper and OCV3Wrapper) and reference both wrappers in my project. I had to renamed libraries from one package (2.x) and reference them manual because: Can we add 2 different versions of same package in NuGet. I read about external aliases and I used external alias in one of the wrappers (2.x in my case).
But I have some major problems:
My renamed libraries are not copied to the launch project build (that one which reference both wrappers), but is in build of the 2.x wrapper
It doesn't work because yet it says it cannot find a type from my 2.x wrapper even when I manually copy my renamed libraries from 2.x wrapper.
What is the correct approach for this scenario in C#?
I want to use both wrappers in solution because the 2.x version contains algorithms (SIFT and SURF) and 3.x version contains algorithms (Kaze and AKaze).
I can live that with both packages coming from somewhere other than NuGet, but I prefer that 3.x comes from NuGet and the 2.x version is manually configured.

As already stated, there is nothing wrong with referencing 2 different versions of a NuGet package, as long as it's in different Visual Studio Projects that those references are made.
But this is also where the easy part ends, but I think there are a few options left. Depending on your needs, I see the following options.
Create a post build step which registers the multi-versioned assemblies into the GAC. As long as each assembly have different assembly version, the CLR will pick up the right assembly from the GAC when needed.
Create a post build step which copies the different assemblies into a subfolder of your application bin folder like bin/package-v1 and bin/package-v2. Then you can, in your application, override the AssemblyResolve event as described here: https://msdn.microsoft.com/en-us/library/ff527268(v=vs.110).aspx. This will make it possible for you to load the assembly in the right version at the time of need.
If you don't want to play around with AssemblyResolve, then you can also modify your web/app.config to do assembly redirect/probing as described here: https://msdn.microsoft.com/en-us/library/4191fzwb(v=vs.110).aspx
Hope this helps a bit, so you don't have to modify third party source code next time.

OK so, I solve this by downloading whole sourcecode for 2.X wrapper version.
Renamed its namespace to ABCDEF2 where ABCDEF was original namespace. Build my own nuget package with my own key and... publish it to our private nuget server.
This is such a lame solution but there is no other way than manually downloading the original packages and reference it directly with different filename etc and you loose nuget advantages.

Related

Different versions of same DLL in Multiple nuget package in Same .Net 6 Project

I have one base nuget library called Foundation.dll.
I have another 5 nuget libraries which are using a different version of Foundation.dll.
Everything is in one project.
My question is when I build a project, VS .Net is obviously going to put only one Foundation.dll in the bin/debug folder. So how VS/.Net decides which nuget package's foundation.dll should be put in the bin/debug folder. Is it randomly?
If I do reference Foundation.dll directly in the project then it is putting my direct reference version into the bin/debug folder but for some other developers in the team, it is putting an older version.
it is very scary that the same exact branch code in 2 different machines works differently. I added one argument in one of Foundation.dll's methods & for one developer it is working but for another developer, the same exact code gives a compilation error.
What is the ultimate solution to this problem? What change should I make in my project?
Thank you.
This is a difficult topic and yes, there are a lot of factors that determine which version is being put to the bin folder. Normally, the compiler chooses the latest version from all the dependencies automatically. But particularly if you have several "final" assemblies in your solution (e.g exe's, unit test libraries) the compiler sometimes gets it wrong. Usually, the code works anyway, but I agree, this is scary.
The actual outcome may depend on the build order, build environment (whether building from the command line or within VS, etc.). Me and my team has had a hard time figuring out the best way around this problem.
The safest approach we found is to reference the latest version of your package directly in the project. This does not need to be the latest version available, but the latest version used anywhere within your solution. Of course, this only works if the versions are backwards compatible. If some library requires an older version of the dependency and you can't rebuild that library, you are in for really big trouble.
I've met the same issue. One project in the solution was depending on .net standard version of a library, while others were expecting a classic framework version.
As PMF wrote, which library will finally occur in the output depends on a build order.
I've solved it by copying the .net standard version into the output folder on post-build events.
The output should not depend on random things, there's some (complex) rules for these situations:
https://learn.microsoft.com/en-us/nuget/concepts/dependency-resolution
It should choose the direct dependency over the indirect ones.
Do you still get different results when doing "rebuild all"?

Adding system references to .NET Core application

Okay, this is (or at least should be) a stupid question: How do I add a reference to a system assembly in .NET Core projects?
I have a .NET Core class library. If I right click on Dependencies, there is still a Add Reference... command, but it only allows me to add references to my other projects. There is now an SDK section, but right clicking there provides no option to add new references.
This was so straight forward before. I don't understand why this has changed or how I now add a reference to something like Microsoft.Win32.Registry. (My understanding is I need a NuGet package for this assembly, but my question still stands about adding system references.)
Even if your system contains this assembly it does not gurantee that other systems also contain it. .Net Core is about cross platform so I do not think there is this assembly in Linux system. So you should distribute not only your code but some of "system" dll as well. And it is easier to update only one nuget package for adding new functionality, bug-fixing, etc than update all framework.

NuGet cross-project dependencies in shared library

The setup: I've created a library targeting .Net Standard 2.0 in VS 2017 and this library uses NuGet to reference a 3rd party driver and manage its dependencies. So far, so good.
The next step is to create an application that uses the (shared) library, in this case a console app targeting .Net Core. I can, of course, add a reference to the DLL(s) that form the shared library. That compiles but doesn't run because the 3rd party stuff is missing. I could of course just copy all required DLLs to the application but for obvious reasons I'd rather use NuGet.
I'm not very experienced with NuGet, never used it in this constellation and having read articles like NuGet cross-project dependency I'm getting the impression I need to fiddle with the application's project file in order to get the library in a complete form but surely that can't be the way forward.
So my question is - is the problem on the side of the library, i.e. do I need to build or export in a particular way, or on the side of the application which, IMHO, shouldn't need to know that level of detail about some library it consumes.
Any help much appreciated!
I'm sharing a large, complicated library this way with several other solutions.
First, set up your library. Right click on the library's project name and choose Properties. About halfway down you'll see a tab labeled Packages. You can use that to auto-generate the NuGet package every time you rebuild the project. Just increment the version number. I use four position version numbering -- the first three are semver-style (major release, minor release, patch release), and the fourth one I increment manually for each new build.
I recommend creating a folder on your drive or network specifically for your local NuGet packages. You can create folders under that for each project. Then you point your debug and release build output to that project folder, and the NuGet package will be generated there, too.
Finally, back in Visual Studio, go to Tools -> Options -> NuGet Package Manager -> Package Sources and add that top-level folder as a package source.
From there it's simple -- open your NuGet dependencies in your consuming app. There's a drop-down at the top right where you can choose the package source. It will automatically search all the child folders and find whatever packages you've created. Now when you tweak your library, it's just a single click to update the client apps.

NuGet or assemblies folder for shared 3rd party DLL's?

I have about 10-15 projects with separate solutions that reference 3rd party DLL's in a microsoft .NET shop. One of the problems that we want to address is consistency of the versions of the DLL's used across projects (E.G. Netwonsoft 8.0.3 in all projects as opposed to separate versions depending when the project was created).
I have seen this done in two separate ways in my previous positions and was wondering if there are any other options to solve this problem.
I have used a corporate NuGet for all third party DLL's referenced within a solution for any project within the company. The DLL's would be updated and then made available to the developers in the projects to pull down and upgrade (if needed) within the solutions on their own.
Another company had an assemblies folder in source that housed all "approved" third party DLL's and all references lived within this directory.
I did see this question but it only offered one of the two solutions above: Where should you store 3rd party assemblies?
Are there other options aside from the ones listed above?
Whenever possible use NuGet. Primary reason being that Git doesn't very much handle large binaries well and using LFS for this doesn't make much sense, since there is a valid alternative. TFVC has fewer issues with large binaries, but I'd keep future migration to Git in mind if you're on TFVC.
Keep in mind that not just NuGet, but likely also npm and other package sources are of interest in this case.
If you want to enforce a certain version being used, create a custom task that you hook into the CI pipeline. That way you can easily give off warnings or setup some kind of policy. The custom task could take the packages.config file, scan the referenced packages and then query the TFS/VSTS package management feed to see if it's using the latest version (or the is using the latest minor version)... (or is using at least x versions back)... or fetches the approved versions from a json file or xml file from somewhere and validates against that...
In your source control, Commit and Push to Master with the desired dependency DLLs when the repository is first populated. Since all users, even on other branches, will then be pulling from the repository, you're ensuring they receive all the DLLs they need. This only becomes a problem if you're referring to DLLs in the GAC, which is resolved either by GACUtil or just making sure everyone is using the same Windows version.

Share code between multiple .NET Core projects

I would like to know how I can share c# source codes between two (or more) .NET Core projects (commandline projects!).
As far as I understand, I can not link to source files in different directories in xproj/project.json based projects. I noticed that it now seems to be recommended to create nuget packages for everything. But is it really necessary for me to setup a private repository and create a nuget package only to be able to share some common source units?
VS2015 contains a template for .NET Core library which may be suitable for building a shared lib. Is it possible to link this lib to a project without a nuget package?
.NET Core Library is an excellent solution for you.
Do it the same way as in standard C# solution - just create the project and reference this project or add a reference to DLL file.
You don't need to use a Nuget, for your own purpose. Nuget packages could be useful to distribute your dll outside.
Clarification:
I miss one point - I'm using VS2015, but I have included Class Library project in my solution, and I'm referencing by project, not by DLL file, and this works fine in ASP.Net Core.
I also have a different project, where referencing DLL file directly working fine, but this is the previous version of ASP.NET app (not Core) - seems NET Core doesn't support this way like as the previous version (yet?).
Sorry for confusing you, sometimes it's too many technologies ;)
So could you just include ClassLibrary project into solution with your project and refer it as a project?
I have achieved this by using source control to branch from my commonly used projects in each new solution, and again merging back to the master branch if I make any changes.
Alternatively, baring in mind that NuGet is only an archived collection of files, you could keep this NuGet package locally, or even create a Template for Visual Studio that has the common libraries by default.
There are a wide range of possibilities that are down to your preference, and current environment state (I.E: Able to setup Source Control, or a package repository).

Categories

Resources