C# build against non specific version of strong-named assembly - c#

According to MSDN:
When you build a .NET Framework application against a specific version
of a strong-named assembly, the application uses that version of the
assembly at run time.
https://msdn.microsoft.com/en-us/library/7wd6ex19(v=VS.100).aspx
Question
Is there a way, to build a .Net Framework application against a strong-named assembly, so that it does not require the specific version at run time?
The quote from MSDN seems to imply that ("against a specific version of a strong-named assembly")
But how to do that. How do I build against a non specific version of a strong named assembly?
All tests I did tell me, that if I build against a strong named assembly, it will always require that version at runtime.
Except when I use Publisher Policys or Assembly Redirects.
Update:
But when I check for example this nuget Package:
https://www.nuget.org/packages/Microsoft.Owin.Security.OAuth.
It says that it accepts Newtonsoft.Json greater then 6.0.4.
And I want to understand how they do that? Since Newtonsoft.Json is a strongly named assembly. And I don't see any assembly redirects and I think there is also no publisher policy. Or do I miss something?

This is handled by assembly redirection, as you've already mentioned.
The NuGet dependency management for the packet manager itself, not the assembly references. You still have strict binding for the references in your project, and this can cause collisions when you end up with two versions of the same assembly in the same AppDomain as usual. NuGet doesn't even try to solve the problem.
When that conflict arises, you're back to square one - you need to add binding redirects. If that isn't possible (for incompatible versions of the assembly, for example), you're in for a lot of fun.
The policy NuGet uses to pick the best version of the library is quite simple: get the lowest possible major + minor version, and the highest possible patch version (the third version number). Again, this only happens when updating the packages, not at compile-time or runtime. This allows NuGet to pick a compatible version of a dependency when you have multiple packages that have different requirements. However, it isn't transitive - it only helps if all your references are in the same project. If you're referencing a project that NuGet's a different version of the dependency, you're back at the original problem again.

Related

Can't find correct version of WebHostBuilderContext in a multitarget project

I have a project that was originally targeting net472, and now must be converted to target both net472 and net5.0.
After I've added net5.0 to it became impossible to build the project because wherever there is mention of WebHostBuilderContext, it uses the version from the net472 package (Microsoft.AspNetCore.Hosting.Abstractions), and not the newer version from net5.0 (Microsoft.AspNetCore.App.Ref), causing type mismatch(they are considered different types).
Apparently since netcore2.1 there has been a large change regarding the Hosting namespace, and I need to somehow instruct the IDE to use the correct version of the mentioned class depending on the build target.
There is no explicit reference to Microsoft.AspNetCore.Hosting.Abstractions or Microsoft.AspNetCore.App.Ref in this project, they are transitively included from other dependencies, so I can't find a way to make use of aliases to explicitly point to the correct assembly. When I use precompiler directives it always sees the Microsoft.AspNetCore.Hosting.Abstractions and doesn't recognize the Microsoft.AspNetCore.App.Ref version.
How can I solve this dependency hell?
I would strongly advise against having one ASP.NET project that is both .net framework 4.x and .net (core) 5.0. That's compatibility hell and asking for problems. If you need specific data from the Context in other projects, consider building a layer of abstraction (adapter or bridge pattern) and only provide (e.g. inject) a framework-independent interface to the other modules.

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.

Using two different versions of same the NuGet package

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.

Modify Assembly Version and References (.NET)

I have an application exe plus 3 referenced assemblies in a folder. Compiled in VS2010, CLR 4.0.
I'd like to modify the version of all 4 assemblies to match (1.0.0.0) and also modify the reference section in each of those assemblies to match the new version number.
Is that possible after the application was already build outside the IDE?
EDIT:
Here is the scenario: Our dlls are often installed in the GAC with a specific version. The version is only incremented when commercial products are released. We have many self written development tools that use some of those dlls that are installed in the GAC. The tools are build at a certain point and not rebuild when the code has changed. The CLR prefers to load the assembly from GAC though instead of the local assemblies, so many times our tools do not use the assemblies that they were build with. Thats a huge problem and I don't see how it could be solved otherwise.
Use Reflector and its plugin Reflexil; of course, if the assemblies are signed they won't work together anymore (actually I think they won't work at all?). Otherwise you won't even need to modify the references I think.
Edit: also, Marc is absolutely right; can't imagine what scenario would absolutely require you to do this, it's quite hackish.
The simplest option is to simply rebuild and redeploy. There are things you can do in config (runtime/assemblyBinding/dependentAssembly/bindingRedirect), but that seems overkill here, since I'm not sure how you would go about changing the version numbers of the assemblies without rebuilding them, especially if they are signed/strong-named (the runtime will detect evil-doers).
It sounds like making work to me...
If the dlls are yours, just rebuild them with the right version meta. If they aren't yours, perhaps don't monkey with them.
Sounds like you need a publisher policy or a binding redirect. This will enable your assemblies to always use the latest version, or to use a specific version of a referenced assembly.

async/await in .NET 4.0: a Compatibe Set of DLLs?

I would like to use async/await syntax when targeting .NET FX 4.0.
I fetched the Microsoft.Bcl.Async.1.0.168 Nuget package. It has the assembly Microsoft.Threading.Tasks, Version=1.0.12.0 which implements all the magic and has a reference to System.Runtime, Version=1.5.11.0.
The System.Runtime assembly is available in the companion Nuget package Microsoft.Bcl.1.1.8, but has a different version 2.6.8.0 in there.
As a result, its usages won't compile without special tricks and hacks.
The DLL reference does not resolve because of the version number mismatch.
So, is it possible to get a consistent set of BCL Async DLLs which reference one another by matching version numbers and which can be compiled right away?
(Tried looking in other Nuget versions or other target ilb folders, found some matching versions but they're for a different platform and with a different set of classes, e.g. with a duplicate Task class)
UPD: Also mind the runtime behavior: with netfx45, these assemblies get unified into runtime and work like a charm, but on a vanilla netfx40 system you'd get a System.IO.FileLoadException with Could not load file or assembly 'System.Threading.Tasks, Version=1.5.11.0, […]
All you need is the one Nuget package, and VS2012 or higher. (with Nuget 2.3 or higher)
https://www.nuget.org/packages/Microsoft.Bcl.Async
Nuget will install all dependencies with the correct version (unless you specify otherwise). I've done this many times, and I'll tell you right now you only need to use that one package, and if its not working there is something else wrong with your setup.
If you don't have VS2012, you can download the Express (free) version in order to use this.
If my word isnt enough, you can read the official MSDN blog on the subject.
http://blogs.msdn.com/b/bclteam/archive/2012/10/22/using-async-await-without-net-framework-4-5.aspx
http://blogs.msdn.com/b/bclteam/archive/2013/04/17/microsoft-bcl-async-is-now-stable.aspx

Categories

Resources