我目前正在开发.NET Compact Framework项目,该项目使用DotNetZip来读取ZIP文件。该项目分为两部分。一个独立于平台的库,应该可用于CF项目和桌面项目。这个公共库包含用于提取ZIP文件的代码。问题是DotNetZip库有两个不同的DLL,一个用于.NET CF,另一个用于.NET Desktop Framework。在桌面框架上使用库的CF版本是不可能的,反之亦然,但它们共享相同的界面。
如何在Visual Studio中组织我的项目以便能够使用公共邮政编码并动态加载相应的DLL(然后由邮政编码使用)?还应该可以在PC上执行CF应用程序,那么有没有办法在运行时选择DLL?
答案 0 :(得分:1)
<强>更新强>
技术上不受支持但有效的解决方案是p / Invoke LoadLibrary并在过程的早期专门加载正确的DLL。所有托管和p / Invoke'd库都“按需”加载。当您调用依赖于该程序集中某个类型的方法时,CLR将为您加载它们(注意:这是“不支持的”部分;这是不记录的,并且可能在将来发生变化CLR版本。)
该方法有效,因为如果程序集是通过LoadLibrary
加载的,则CLR加载程序会“找到”它,运行时将不再尝试加载它。我们在CF上使用这个技巧在进行大量内存分配之前预加载程序集,以避免内存不足的情况。
所以,你应该能够做到:
public static void Main()
{
LoadCorrectDLLs();
// .NET will ensure DotNetZip is loaded at this point.
MethodInThisAssembly();
}
public static void MethodInThisAssembly()
{
// Since MethodInThisAssembly uses DotNetZip,
// its assembly will get loaded immediately before this method is called.
IDotNetZipInterface x = null;
...
}
public static void LoadCorrectDLLs()
{
// p/Invoke LoadLibrary to load the correct version of DotNetZip.
}
请注意,以下不工作:
public static void Main()
{
LoadCorrectDLLs();
// This line would force DotNetZip to get loaded before Main() is called
IDotNetZipInterface x = null;
}
老答案;仅适用于桌面框架:
一个技巧是将它们放在DLL加载期间找不到的目录中(例如,可执行文件目录的不同子目录)并处理AppDomain.AssemblyResove。大卫莫顿有一个不错的写作on his blog。