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

var*_*osh 12 c# .net-3.5

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

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

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

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

小智 10

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

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

在您的代码中使用DLL时用于extern alias指定您要引用的DLL.

extern alias Assembly1Reference;
using Assembly1Reference::AssemblyNamespace.MyClass;
Run Code Online (Sandbox Code Playgroud)

如果你这样离开,你很可能会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;
}
Run Code Online (Sandbox Code Playgroud)

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

<Reference Include="MyAssembly_3.6.2.0, Version=3.6.2.0, Culture=neutral, PublicKeyToken=12341234asdafs43, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>Resources\Assembly1.dll</HintPath>
      <Aliases>Assembly1Reference</Aliases>
</Reference>
Run Code Online (Sandbox Code Playgroud)

我知道这已经晚了但希望它能帮助从现在开始访问此页面的任何人.


Che*_*eso 0

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

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

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

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