使用两个具有相同名称和相同名称空间的DLL

我有一个项目需要引用两个具有相同名称的DLL。 DLL名称不强,具有相同的名称。

我需要访问每个DLL中的某些类型,但这些类型具有相同的完全限定名称。 所以假设第一个是带有someProduct.Type1 ,第二个是带有someProduct.Type1

如何在同一个项目中访问两个Type1类?

我已经尝试使用extern alias ,但它需要我更改其中一个DLL的名称。

如果您的两个DLL具有相同的名称,则必须重命名它们。 例如Assembly1.dll和Assembly2.dll。

像往常一样在项目中添加这些DLL作为引用,并在每个引用的属性中指定别名。

在使用DLL时,在代码中使用extern alias来指定要引用的dll。

 extern alias Assembly1Reference; using Assembly1Reference::AssemblyNamespace.MyClass; 

如果你这样离开它,你很可能会得到一个FileNotFoundException ,说它无法加载文件或程序集。 要解决此问题,您需要添加一个ResolveEventHandler ,它将加载您尝试使用的正确程序集。 为此,您必须准确指定存储DLL文件的位置。 在下面的例子中,我手动将Dll文件复制到项目调试文件夹。 如果它显示“assembly1的名称”,您可以在引用DLL,构建项目并使用记事本打开csproj文件后找到该名称。 要查找的内容将在我的示例代码下面。

 extern alias Assembly1Reference; extern alias Assembly2Reference; static void Load() { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; Do(); } static void Do() { new Assembly1Reference.Assembly.Class(); new Assembly2Reference.Assembly.Class(); } static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { string currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); if(args.Name == "Name of assembly1")//Found in csproj file after referenced and built { return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(currentPath, "Assembly1.dll")); } if(args.Name == "Name of assembly2")//Found in csproj file after referenced and built { return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(currentPath, "Assembly2.dll")); } return null; } 

正如所承诺的,这是csproj文件中的引用。 名称是include属性中的所有内容。

  False Resources\Assembly1.dll Assembly1Reference  

我知道这已经很晚了,但希望它能帮助任何人从现在开始访问这个页面。

使用extern alias将程序集置于不同的名称空间中。 如果您可以区分命名空间,则应该能够using altType1 = someProduct.Type1来为该类型创建本地别名。

首先从命令行限定程序集:

 /r:ProductA=companyDLLA.dll /r:ProductB=companyDLLB.dll 

然后使用extern alias引用它们:

 extern alias productA; extern alias productB; 

最后,您可以为本地类型添加别名:

 using productTypeA = productA.Type1; using productTypeB = productB.Type1; 

我可以想到两种方法来处理这个问题。

  1. 将每个DLL加载到单独的AppDomain中。 您必须跨AppDomain边界进行调用以触发各种属性和方法。

  2. 在加载程序集之前,反汇编然后重新组装每个程序集并将它们放入唯一(可能是动态生成的)名称空间。 有一些工具可以帮助解决这个问题( 1 )( 2 )。 你可以自动化它。

但我的基本感觉是,你真的不应该这样做。 在上游解决这个问题比在已经编译好的程序集之后解决它更容易。

所提出的解决方案都不适合我。 我不得不重新编译DLL并给它们不同的标识,即在项目设置中更改“程序集名称”。

如果您无法重新编译DLL,另一种解决方案是创建具有合适名称的包装器。