Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用两个具有相同名称和相同命名空间的DLL_C#_.net 3.5 - Fatal编程技术网

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

C# 使用两个具有相同名称和相同命名空间的DLL,c#,.net-3.5,C#,.net 3.5,我有一个项目,需要引用两个同名DLL。DLL不是强名称,具有相同的确切名称 我需要访问每个DLL中的某些类型,但这些类型具有相同的完全限定名。 假设第一个是companydell.dll,带有someProduct.Type1和 第二个是companydell.dll,带有someProduct.Type1 如何访问同一项目中的Type1类 我已经尝试使用外部别名,但它要求我更改其中一个DLL的名称 我可以想出两种方法来处理这个问题 将每个DLL加载到单独的AppDomain中。您必须跨越App

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

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

如何访问同一项目中的
Type1


我已经尝试使用
外部别名
,但它要求我更改其中一个DLL的名称

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

  • 将每个DLL加载到单独的AppDomain中。您必须跨越AppDomain边界进行调用,以获取各种属性和方法

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


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

    使用
    外部别名
    将具有不同名称空间的程序集引入。如果可以区分名称空间,则应该能够使用
    使用altType1=someProduct.Type1
    为该类型创建本地别名

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

    /r:ProductA=companyDLLA.dll
    /r:ProductB=companyDLLB.dll
    
    然后使用外部别名引用它们:

    extern alias productA;
    extern alias productB;
    
    最后,您可以为本地类型别名:

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

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

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

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

    extern alias Assembly1Reference;
    using Assembly1Reference::AssemblyNamespace.MyClass;
    
    如果您将其保持这种状态,您很可能会得到一个
    FileNotFoundException
    ,说明它无法加载文件或程序集。要解决此问题,您需要添加一个
    resolveventhandler
    ,它将加载您尝试使用的正确程序集。要做到这一点,您必须准确地指定存储DLL文件的位置。在下面的例子中,我手动将Dll文件复制到projects debug文件夹。其中显示“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属性中的所有内容

    <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>
    
    
    假的
    资源\Assembly1.dll
    汇编1参考
    

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

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


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

    当我遇到这个问题时,我创建了两个不同的包装器项目,每个项目引用不同版本的DLL,并使用nuget将DLL嵌入到包装器项目中,以防止在构建中发生冲突。

    这完全属于“如果您试图这样做,您的设计将被严重破坏”这一类别。明确同意,这是针对需要来自公司产品的两个版本(使用.NET构建)的信息的工具。但是这里讨论的产品是受监管的,因此不能更改。@cdhowie不一定。有很多不同的场景涉及新旧版本之间的转换,例如基准比较。Cecil可能是比ildasm更好的方法,因为您可以直接使用C#操作IL。对于上面的#1:如何在同一项目中添加对两个同名DLL的引用?不幸的是,这两个dll具有相同的名称。即/r:ProductA=companyDLA.dll/r:ProductB=companyDLA.dlli无法重命名dll的原因是什么?如果我处于您的情况,我会尝试重命名它们
    companydlv1.dll
    和companydlv2.dll`。是的,dll无法重命名。这里讨论的DLL是受监管的,未经正式批准流程(这在我的情况下是不可能的)不得更改。这很有用,我可以部分实现这一点,但我有以下问题。这样做的目的是什么
    static void Do(){new Assembly1Reference.Assembly.Class();new Assembly2Reference.Assembly.Class();}
    另外,通过代码而不是类似app.config解析程序集的优点是什么。在我的例子中,总是加载程序集的最新版本。我应该如何加载特定重命名程序集的确切dll。