0

我目前正在为 .NET Compact Framework 开发项目,该项目使用 DotNetZip 读取 ZIP 文件。该项目分为两部分。一个独立于平台的库,应该可用于 CF 项目和桌面项目。这个公共库包含用于提取 ZIP 文件的代码。问题在于 DotNetZip 库有两种不同的 DLL,一种用于 .NET CF,一种用于 .NET Desktop Framework。不能在桌面框架上使用库的 CF 版本,反之亦然,但它们共享相同的界面。

如何在 Visual Studio 中组织我的项目,以便能够使用公共邮政编码并动态加载适当的 DLL(然后由邮政编码使用)?也应该可以在 PC 上执行 CF 应用程序,那么有没有办法在运行时选择 DLL?

4

1 回答 1

1

更新:

一个技术上不受支持但可行的解决方案是 p/Invoke LoadLibrary 并在此过程的早期专门加载正确的 DLL。所有托管和 p/Invoke 的库都“根据需要”加载。当您调用依赖于该程序集中其中一种类型的方法时,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。大卫莫顿在他的博客上有一篇不错的文章。

于 2010-07-01T10:29:36.557 回答