Это может выглядеть как дубликат, но это не так, это другой вопрос!
Сценарий таков: у меня есть веб-приложение, которое выполняет итерацию по всем 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, использовать ее, выгрузить и двигаться дальше.
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();
}
Если вы хотите версировать элементы, другим подходом было бы добавление некоторых метаданных в ваш интерфейс.
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.
lock
в список элементов для доступа к коду является для вас проблемой, я настоятельно рекомендую использовать существующую реализацию системы подключаемых модулей. Загрузка нескольких сборок с одинаковым идентификатором в один и тот же домен приложений вызовет множество интересных проблем, как только вы откажетесь от очень простых онлайн-функций ...