在运行时选择适当的平台相关DLL

时间:2010-07-01 10:20:14

标签: c# .net dll compact-framework loadlibrary

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

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

1 个答案:

答案 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