在同一文件夹中使用相同程序集的不同版本

我有以下情况

项目A

- Uses Castle Windsor v2.2 - Uses Project B via WindsorContainer 

项目B

  - Uses NHibernate - Uses Castle Windsor v2.1 

在项目AI的bin文件夹中有dll Castle.DynamicProxy2.dll v2.2和NHibernate dll。 现在的问题是,NHibernate是依赖于Castle.DynamicProxy2.dll v2.1不在那里。 我如何解决这种情况。

我用下面的configuration来解决这个问题。

 <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Castle.DynamicProxy2" publicKeyToken="407dd0808d44fbdc" /> <codeBase version="2.1.0.0" href="v2.1\Castle.DynamicProxy2.dll" /> <codeBase version="2.2.0.0" href="v2.2\Castle.DynamicProxy2.dll" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" /> <codeBase version="1.1.0.0" href="v2.1\Castle.Core.dll" /> <codeBase version="1.2.0.0" href="v2.2\Castle.Core.dll" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration> 

一种解决scheme(或解决方法)是将两个版本都安装在需要运行软件的计算机上的全局程序集caching (GAC)中,然后使用强名称引用程序集。 这假设组件确实有很强的名字。

如果您的开发人员不止一名,或者您打算将解决scheme部署到多台计算机(例如作为最终用户应用程序),那么安装到GAC中将会很麻烦。 在这种情况下,我相信(但我可能是错的),你唯一的select是将两个版本之一合并到需要该版本的程序集中。 在你的具体情况下,你需要将Castle.DynamicProxy2.dll v2.1合并到NHibernate.dll

您可以使用称为ILMerge的工具合并程序集。 你需要运行的命令如下所示(未经testing):

 ILMerge /t:library /internalize /out:Deploy/NHibernate.dll NHibernate.dll Castle.DynamicProxy2.dll 

/internalize开关告诉ILMerge标记输出程序集internal的第二个程序集(本例中为Castle)的所有types。 如果没有这个,当您尝试编译引用您的新NHibernate.dllCastle.DynamicProxy2.dll v2.2的货架版本的项目时,您可能会收到编译错误,因为它们将包含具有完全相同名称的类。

有一点非常非常重要,如果他没有引起足够的重视,可能会错过。

您在codeBase版本标签中编写的程序集必须是强命名的。

从以下链接: http : //msdn.microsoft.com/en-us/library/efs781xb.aspx

对于没有强名称的程序集,将忽略版本,加载程序使用<dependentAssembly>内的<codebase>的第一个外观。 如果应用程序configuration文件中存在redirect到另一个程序集的绑定的条目,则即使程序集版本不匹配绑定请求,redirect也将优先。

我不认为Hemanshu Bhojak的解决scheme是一个很好的解决scheme,因为您不想将同一个程序集的两个版本加载到相同的上下文中。 本文解释了为什么:

http://msdn.microsoft.com/en-us/library/dd153782.aspx#avoid_loading_multiple_versions