我有一个项目需要引用两个具有相同名称的DLL。 DLL名称不强,具有相同的名称。
我需要访问每个DLL中的某些类型,但这些类型具有相同的完全限定名称。
所以我们假设第一个是companyDLL.dll someProduct.Type1
和
第二个是companyDLL.dll with someProduct.Type1
。
我怎样才能访问这两个 Type1
同一个项目中的课程?
我已经尝试过使用了 extern alias
,但它需要我更改其中一个DLL的名称。
我有一个项目需要引用两个具有相同名称的DLL。 DLL名称不强,具有相同的名称。
我需要访问每个DLL中的某些类型,但这些类型具有相同的完全限定名称。
所以我们假设第一个是companyDLL.dll someProduct.Type1
和
第二个是companyDLL.dll with 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属性中的所有内容。
<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>
我知道这已经很晚了,但希望它能帮助任何人从现在开始访问这个页面。
运用 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;
我可以想到两种方法来处理这个问题。
将每个DLL加载到单独的AppDomain中。您必须跨AppDomain边界进行调用以触发各种属性和方法。
在加载程序集之前,反汇编然后重新组装每个程序集并将它们放入唯一(可能是动态生成的)名称空间。有一些工具可以帮助解决这个问题(1)(2)。你可以自动化它。
但我的基本感觉是,你真的不应该这样做。在上游解决这个问题比在已经编译好的程序集之后解决它更容易。
所提出的解决方案都不适合我。我不得不重新编译DLL并给它们不同的标识,即在项目设置中更改“程序集名称”。
如果您无法重新编译DLL,另一种解决方案是创建具有合适名称的包装器。