Выберите подходящую платформенно-зависимую DLL во время выполнения - PullRequest
0 голосов
/ 01 июля 2010

В настоящее время я работаю над проектом для .NET Compact Framework, который использует DotNetZip для чтения ZIP-файлов. Проект разделен на две части. Одна независимая от платформы библиотека, которая должна быть доступна как для CF-проекта, так и для настольного проекта. Эта общая библиотека содержит код для извлечения ZIP-файлов. Проблема в том, что есть две разные библиотеки DLL библиотеки DotNetZip, одна для .NET CF и одна для .NET Desktop Framework. Невозможно использовать версию библиотеки CF в Desktop Framework и наоборот, но они используют один и тот же интерфейс.

Как мне организовать свои проекты в Visual Studio, чтобы иметь возможность использовать общий zip-код и динамически загружать соответствующую DLL (которая затем используется zip-кодом)? Также должно быть возможно выполнить приложение CF на ПК, так есть ли способ выбрать DLL во время выполнения?

1 Ответ

1 голос
/ 01 июля 2010

ОБНОВЛЕНИЕ:

Технически неподдерживаемое, но работающее решение - это 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.У Дэвида Мортона есть приличная статья в его блоге .

...