Это может выглядеть как дубликат, но это не так, это другой вопрос!

Сценарий таков: у меня есть веб-приложение, которое выполняет итерацию по всем DLL, динамически загружаемым в систему, чтобы получить доступ к методу из него и получить данные. Эти dll добавляются пользователями с сайта.

Псевдокод будет примерно таким:

pulic void GetNews(){
    foreach(var i in ListOfDllPaths){
        Assembly dll = Assembly.Load( File.ReadAllBytes(i));
        SomeInterface if = CreateInstance(dll); //This methods does all the validation and such
        if.DoMethod();
    }
}

Теперь проблема в том, что при каждом вызове GetNews () одни и те же библиотеки загружаются заново, причем одни и те же библиотеки загружаются несколько раз. Я мог бы использовать Assembly.LoadFrom или LoadFile, чтобы избежать этой проблемы, но тогда я бы заблокировал файл, который мне не нужен, потому что я хочу иметь возможность удалить его.

Другой вариант - использовать новый домен приложения для их загрузки, вызова метода и выгрузки, но тогда мне также придется загрузить интерфейсную dll в этом домене, путь к которому я действительно не знаю в веб-приложении. . Не говоря уже о переносе данных из одного домена приложения в другой - это боль, и ее слишком сложно выполнить.

Третий вариант - использовать теневую копию, но тогда я не смогу удалить теневую копию с теми же результатами.

Параметры? В основном мне нужно загрузить dll, использовать ее, выгрузить и двигаться дальше.

0
Cristiano Coelho 30 Май 2013 в 05:05
Возможно, я неправильно понимаю проблему здесь, но если вы хотите убедиться, что вы просто загрузили dll один раз, не могли бы вы просто сохранить список имен файлов, которые вы уже загрузили, и каждый раз проверять этот список, чтобы убедиться, что вы загружаете только новые?
 – 
joshuahealy
30 Май 2013 в 05:09
Я отредактировал ваше название. См. Раздел «Должны ли вопросы включать« теги »в свои заголовки?», где консенсусом является «нет, они должны нет".
 – 
John Saunders
30 Май 2013 в 05:10
1
Если вам нужно выгрузить его, используя отдельный домен приложения, это ваш единственный вариант.
 – 
Yaur
30 Май 2013 в 05:18
Проблема с сохранением списка уже загруженных dll будет связана с параллелизмом, учитывая, что это веб-приложение, как это будет работать? Из-за этого запросы Htpp будут сериализованы, не так ли? Только 1 запрос за раз, так как мне пришлось бы заблокировать список, добавить элемент, освободить его или добавить какой-то механизм чтения-записи.
 – 
Cristiano Coelho
30 Май 2013 в 05:24
Если добавление lock в список элементов для доступа к коду является для вас проблемой, я настоятельно рекомендую использовать существующую реализацию системы подключаемых модулей. Загрузка нескольких сборок с одинаковым идентификатором в один и тот же домен приложений вызовет множество интересных проблем, как только вы откажетесь от очень простых онлайн-функций ...
 – 
Alexei Levenkov
30 Май 2013 в 06:16

1 ответ

Лучший ответ

Если вам действительно нужно выгрузить его, у вас нет другого выбора, кроме как использовать отдельный домен приложения (см. Как, например, выгрузить сборку из основного домена приложения? )

Если вам нужно загрузить каждую сборку только один раз, но вы не заботитесь о выгрузке старых, вам нужно управлять отслеживанием того, какие сборки загружаются самостоятельно. Любой простой способ сделать это - получить хэш каждого файла перед его загрузкой. Что-то вроде:

Dictonary<string,bool> loadedAssemblies = new Dictonary<string,bool>();

using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
    var hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
    if(loadedAssemblies.ContainsKey(hash)) continue;
    loadedAssemblies[hash] = true;
    Assembly dll = Assembly.Load( File.ReadAllBytes(i));
    SomeInterface if = CreateInstance(dll); //This methods does all the validation and such
    if.DoMethod();
}

Если вы хотите версировать элементы, другим подходом было бы добавление некоторых метаданных в ваш интерфейс.

3
Community 23 Май 2017 в 15:18
Если dll уже загружена (я нахожу ее в хэше), как мне получить обратно сборку? Стоит ли вместо этого хранить ссылку на сборку?
 – 
Cristiano Coelho
30 Май 2013 в 05:37