Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving compile-time references to different versions of the same .NET assembly in the same application

Tags:

.net

f#

Using PowerPack in F# application targeting .NET 4.0 causes some pain

FSharp.PowerPack.dll is still (Why? Are they going to give up with it?) referencing only FSharp.Core.dll 2.0 which targets .NET 2.0. At the same time FSharp.Core.dll 4.0 is not compatible with .NET 2.0.

How does it go when the both FSharp.Core.dll 2.0 and 4.0 are in GAC? It loads 4.0 as it is compatible with current .NET framework and then tells FSharp.PowerPack.dll that everything is already loaded. This can be seen in the both Visual Studio debugger, when the application loads and in Reflector when walking through dependencies.

Everything is fine until we need to redistribute software in portable way. When we actually need, we are to copy FSharp.Core.dll 4.0 (to sound with .NET 4.0) and FSharp.PowerPack.dll to the application local codebase. And then it (suddenly!) complains that the reference to FSharp.Core.dll 2.0 [from PowerPack] is not met.

The problem can be easily solved in the brutal way like mentioned in F# PowerPack Target Runtime topic by simply redirecting reference to existing version of FSharp.Core.dll.

So what is the question?

The question is why everything is OK without any redirects when we refer assemblies installed to GAC. With GAC it seems to be satisfied with the existence of FSharp.Core.dll 2.0 itself and then it just throws it away, using 4.0 version for all purposes. What is the logic behind this?

Jeffrey Richter's CLR via C# seems to say nothing about it...

like image 437
dluciv Avatar asked May 12 '12 12:05

dluciv


People also ask

What is assemblies explain why assemblies are used in .NET framework?

An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. Assemblies take the form of executable (.exe) or dynamic link library (. dll) files, and are the building blocks of . NET applications.

What is an assembly reference in C#?

Reference assemblies are usually distributed with the Software Development Kit (SDK) of a particular platform or library. Using a reference assembly enables developers to build programs that target a specific library version without having the full implementation assembly for that version.

What is .NET assembly explain its types?

In the Microsoft . NET framework, an assembly is a partially compiled code library for use in deployment, versioning and security. There are two types: process assemblies (EXE) and library assemblies (DLL). A process assembly represents a process which will use classes defined in library assemblies. .

What is assembly in C# with example?

An assembly is a file that is automatically generated by the compiler upon successful compilation of every . NET application. It can be either a Dynamic Link Library or an executable file. It is generated only once for an application and upon each subsequent compilation the assembly gets updated.


1 Answers

First of all you need to know that CLR 4.0 introduces a separate GAC from CLR 2.0. CLR 4.0's GAC sees the old one, but not vice versa.

Now, in the CLR 4.0 GAC there is a redirect - the publisher policy file for FSharp.Core that redirects any request to load version 2.0 to 4.0. This contains essentially the same thing as the config file you link to.

In the CLR 2.0 GAC there is no such redirect, obviously because 4.0 is not in that GAC and wouldn't be compatible anyway.

To have a look yourself, either use the fusion log viewer (fuslogvw) when loading FSharp.Core - it should show the redirect taking place.

Also have a look at the pub.config file which in my CLR 4.0 GAC is in C:\Windows\Microsoft.NET\assembly\GAC_MSIL\policy.2.0.FSharp.Core\v4.0_2.0.0.0__b03f5f7f11d50a3a

like image 122
Kurt Schelfthout Avatar answered Oct 19 '22 22:10

Kurt Schelfthout