解析在同一应用程序中对同一.NET程序集的不同版本的编译时引用(Resolving compile-time references to different versions of the same .NET assembly in the same application)

在针对.NET 4.0的F#应用程序中使用PowerPack会带来一些痛苦

FSharp.PowerPack.dll仍然是( 为什么?他们会放弃吗? )仅引用面向.NET 2.0的FSharp.Core.dll 2.0 2.0。 同时FSharp.Core.dll 4.0与.NET 2.0不兼容。

当FSharp.Core.dll 2.0和4.0都在GAC中时,它是怎么回事? 它加载4.0因为它与当前的.NET框架兼容,然后告诉FSharp.PowerPack.dll已经加载了所有内容。 这可以在Visual Studio调试器中,当应用程序加载时和在Reflector中遍历依赖项时看到。

在我们需要以便携方式重新分发软件之前,一切都很好。 当我们真正需要时,我们将FSharp.Core.dll 4.0 (与.NET 4.0一起发声)和FSharp.PowerPack.dll到应用程序本地代码库。 然后它( 突然! )抱怨没有满足对FSharp.Core.dll 2.0 [来自PowerPack]的引用。

只需将引用重定向到现有版本的FSharp.Core.dll,就可以通过F#PowerPack Target Runtime主题中提到的残酷方式轻松解决问题。

那么问题是什么?

问题是当我们引用安装到GAC的程序集时,没有任何重定向的一切正常。 对于GAC,它似乎对FSharp.Core.dll 2.0本身的存在感到满意,然后它只是抛弃它,使用4.0版本用于所有目的。 这背后的逻辑是什么?

杰弗里里希特通过C# CLR似乎对此一无所知......

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...

最满意答案

首先,您需要知道CLR 4.0从CLR 2.0引入了单独的GAC。 CLR 4.0的GAC看到旧的,但反之亦然。

现在,在CLR 4.0 GAC中有一个重定向 - FSharp.Core的发布者策略文件,它将任何请求重定向到加载版本2.0到4.0。 这包含与您链接到的配置文件基本相同的内容。

在CLR 2.0 GAC中没有这样的重定向,显然因为4.0不在GAC中并且无论如何都不兼容。

要自己看看,在加载FSharp.Core时使用融合日志查看器(fuslogvw) - 它应该显示重定向发生。

另请查看我的CLR 4.0 GAC中的pub.config文件,该文件位于C:\ Windows \ Microsoft.NET \ assembly \ GAC_MSIL \ policy.2.0.FSharp.Core \ v4.0_2.0.0.0__b03f5f7f11d50a3a

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

更多推荐