C# 引用同一程序集的不同版本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/223195/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:50:19  来源:igfitidea点击:

Referencing different versions of the same assembly

c#dllbuild-processassembliesversioning

提问by Dan

If A references assembly B 1.1 and C, and C references B 1.2, how do you avoid assembly conflicts?

如果 A 引用程序集 B 1.1 和 C,而 C 引用 B 1.2,您如何避免程序集冲突?

I nievely assumed C's references would be encapsulated away and would not cause any problems, but it appears all the dll's are copied to the bin, which is where the problem occurs.

我认为 C 的引用会被封装起来并且不会引起任何问题,但似乎所有的 dll 都被复制到了 bin,这就是问题发生的地方。

I understand the two ways around this are to use the GAC or assembly bindings? The GAC doesn't seem like the best approach to me, as I don't like assuming dlls will be there, I prefer to reference dlls from a lib directory in my solution.

我了解解决此问题的两种方法是使用 GAC 或程序集绑定?GAC 对我来说似乎不是最好的方法,因为我不喜欢假设 dll 会在那里,我更喜欢从我的解决方案中的 lib 目录中引用 dll。

Where as assembly bindings don't seem robust to me, what if one version of the assembly has functionality that the other doesn't, will this not produce problems?

由于程序集绑定对我来说似乎并不健壮,如果程序集的一个版本具有另一个版本没有的功能,这会不会产生问题?



In my case its because I'm using a 3rd party dll uses a older version of nHibernate, than I'm using myself.

就我而言,这是因为我使用的第 3 方 dll 使用的是旧版本的 nHibernate,而不是我自己使用的版本。

回答by Kilhoffer

I've achieved the same results using the GAC in the past, but you should question your reasons for having to reference more than one version and try to avoid it if possible. If you must do it, a binding redirectmay help in your case.

我过去使用 GAC 也取得了相同的结果,但您应该质疑您必须引用多个版本的原因,并尽可能避免它。如果您必须这样做,绑定重定向可能对您有所帮助。

Also, have you read thisyet?

另外,你读过这个吗?

回答by Joe

You can add a bindingRedirect elementto your configuration file to specify which version of the assembly you want to use at runtime.

您可以将bindingRedirect 元素添加到配置文件中,以指定要在运行时使用的程序集版本。

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

回答by AlanR

The .NET runtime is perfectly capable of loading multiple versions of the same assembly simultaneously. If you are going to open this can of worms, however, I strongly suggest you stronly name your assemblies and use the Major.Minor.* naming scheme to avoid naming conflicts.

.NET 运行时完全能够同时加载同一程序集的多个版本。但是,如果您要打开这个蠕虫罐头,我强烈建议您只为程序集命名并使用 Major.Minor.* 命名方案以避免命名冲突。

I don't think you should think of a one-size-fits-all approach to using (or not) the GAC. The GAC can be really nice if you want to automagically use new functionality published with future versions of a DLL. Of course, this blessing comes at a cost that new versions might not work exactly like you expect them too :). It's all a matter of what's most practical, and how much control you have over what gets published to the GAC.

我认为您不应该考虑使用(或不使用)GAC 的通用方法。如果您想自动使用未来版本的 DLL 发布的新功能,GAC 会非常好。当然,这种祝福是有代价的,新版本可能也不会像您期望的那样工作:)。这完全取决于什么最实用,以及您对向 GAC 发布的内容拥有多少控制权。

Regards, -Alan.

问候,-艾伦。

回答by Peter Kelly

A seemingly little known way of doing this is to use the extern keyword.

一种看似鲜为人知的方法是使用 extern 关键字。

From C# Reference

来自C# 参考

To reference two assemblies with the same fully-qualified type names, an alias must be specified at a command prompt, as follows:

/r:GridV1=grid.dll

/r:GridV2=grid20.dll

This creates the external aliases GridV1 and GridV2. To use these aliases from within a program, reference them by using the externkeyword. For example:

extern alias GridV1;

extern alias GridV2;

Each extern alias declaration introduces an additional root-level namespace that parallels (but does not lie within) the global namespace. Thus types from each assembly can be referred to without ambiguity by using their fully qualified name, rooted in the appropriate namespace-alias.

In the previous example, GridV1::Grid would be the grid control from grid.dll, and GridV2::Grid would be the grid control from grid20.dll.

要引用具有相同完全限定类型名称的两个程序集,必须在命令提示符下指定别名,如下所示:

/r:GridV1=grid.dll

/r:GridV2=grid20.dll

这将创建外部别名 GridV1 和 GridV2。要在程序中使用这些别名,请使用extern关键字引用它们。例如:

外部别名 GridV1;

外部别名 GridV2;

每个 extern 别名声明都引入了一个额外的根级命名空间,该命名空间与全局命名空间平行(但不位于其中)。因此,可以通过使用它们的完全限定名称(以适当的命名空间别名为根)来毫无歧义地引用来自每个程序集的类型。

在前面的示例中,GridV1::Grid 将是来自 grid.dll 的网格控件,而 GridV2::Grid 将是来自 grid20.dll 的网格控件。

回答by burton

I was required to support multiple versions of an assembly and found this solution:

我需要支持程序集的多个版本并找到了这个解决方案:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="MyAssembly" publicKeyToken="..." />
        <codeBase version="1.1.0.0" href="MyAssembly_v1.1.0.0.dll"/>
        <codeBase version="2.0.0.0" href="MyAssembly_v2.0.0.0.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>