C# 使用两个具有相同名称和相同命名空间的DLL
我有一个项目,需要引用两个同名DLL。DLL不是强名称,具有相同的确切名称 我需要访问每个DLL中的某些类型,但这些类型具有相同的完全限定名。 假设第一个是companydell.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
someProduct.Type1
和
第二个是companydell.dll,带有someProduct.Type1
如何访问同一项目中的Type1
类
我已经尝试使用
外部别名
,但它要求我更改其中一个DLL的名称 我可以想出两种方法来处理这个问题
但我的基本感觉是,你真的不应该这么做。在上游解决此问题比在编译完程序集后解决此问题更容易 使用
外部别名
将具有不同名称空间的程序集引入。如果可以区分名称空间,则应该能够使用使用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。