2015-11-23 2 views
0

Прошу прощения, если у меня возник вопрос о том, на что я уже спросил, и мне ответили, но я застрял здесь и надеялся, что кто-то сможет установить меня по правильному пути еще раз. (Оригинальный вопрос: Get DLL's file name of inherited class)Получить физическое имя файла унаследованного класса

У меня есть абстрактный класс, называемый PluginBase.dll, из которого наследуются другие классы. Все они скомпилированы как разные плагины для серверного приложения. Давайте посмотрим на один из этих плагинов, называется PluginMessaging.dll, который имеет конфигурационный файл с именем PluginMessaging.dll.config

Метод, который считывает параметры конфигурации в базовом классе и выглядит следующим образом:

private void ReadConfig() 
{ 
    _runningDir = System.IO.Path.GetDirectoryName(GetType().Assembly.Location); 
    _pluginFile = System.IO.Path.GetFileName(GetType().Assembly.Location); 
    _configFile = _pluginFile + ".config"; 

    // Do stuff here that reads from _configFile 
} 

Строка кода который присваивает значение _pluginFile, это то, что я получил с первого раза, когда задал вопрос (ответил Damien_The_Unbeliever), и он отлично работает, если есть только один экземпляр файла PluginMessaging и его файла конфигурации.

То, что я пытаюсь сделать сейчас, чтобы сделать две копии скомпилированного плагина, давайте назовем их PluginMessaging_A.dll и PluginMessaging_B.dll, каждый со своим собственным соответствующим конфигурационный файл, PluginMessaging_A.dll.config и PluginMessaging_B.dll.config соответственно.

Проблема, с которой я столкнулась, заключается в том, что серверное приложение выполняет итерацию через все файлы *.dll в своей папке «Плагины», создает экземпляр каждого из них и вызывает метод выше ReadConfig() для каждого. Когда функция вызывается для PluginMessaging_A.dll все работает, как ожидалось, и значение _pluginFile является PluginMessaging_A.dll но когда ReadConfig() функция для второго экземпляра DLL, PluginMessaging_B.dll называется, по какой-то причине, _pluginFile снова решает PluginMessaging_A. Dll

Казалось бы, как если есть таблица в памяти, которая запоминает GetType().Assembly информации для PluginMessaging.dll первый раза, когда он конкретизируется, независимо от того, что физического имени имеет на диск, и сохраняет, что для любых последующих экземпляров одного и те же DLL, хотя и с другим именем на диске.

ответ

1

Казалось бы, как если есть таблица в памяти, которая запоминает GetType(). Информация Assembly для PluginMessaging.dll первого раза, когда он конкретизируется, независимо от того, каких физического имени он имеет на диске и сохраняет это для любых последующих экземпляров одной и той же DLL, хотя и с другим именем на диске.

Это замечание верно. Имя файла не имеет отношения к идентификатору сборки.

Вы думаете вы загружаете две разные сборки, но среда выполнения определяет, что вы пытаетесь снова загрузить ту же сборку - и не загружает ее.

MSDN: Assembly Names:

Среда выполнения не учитывает имя файла при определении идентичности сборочной в.Идентификатор сборки, который состоит из имени сборки, версии, культуры и сильного имени, должен быть ясным для среды выполнения.

Если вы сделать хотите загрузить ту же сборку из двух файлов, вы должны сделать это в отдельных AppDomains. См. How to Load an Assembly to AppDomain with all references recursively?.

В качестве альтернативы вы можете изменить имя, версию, культуру или сильное имя и снова перекомпилировать: тогда у вас будет две разные версии.

+0

Отличный ответ, спасибо. Я боюсь, хотя я не совсем уверен, как применить решение, указанное в ссылке, к моему сценарию, но по крайней мере сейчас у меня есть кое-что, что я могу изучить. Повторная компиляция с новым именем/версией/культурой не совсем осуществима, так как я надеюсь добраться до точки, где может быть сделано любое количество копий плагина, и даны уникальные имена файлов, чтобы поведение каждого определяется его конфигурационным файлом. –

-2

Попробуйте

_pluginFile = System.IO.Path.GetFileName(GetType().Assembly.GetExecutingAssembly().Location); 
+0

«Попробуйте это» - не ответ. Объясните свое решение, поэтому ясно, что вы поняли проблему OP и объяснили свой код, чтобы мы могли проверить, что код, который вы вставили, решает эту проблему. В этом случае это не так: он вернет путь исполняющей сборки к тому типу, который вы вызываете. – CodeCaster

Смежные вопросы