抱歉不得不问一个与我已经问过并得到回答的问题类似的问题,但我被困在这里,希望有人能让我再次走上正确的道路。(原始问题在这里:获取继承类的DLL文件名(
我有一个名为 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
。
我遇到的问题是,服务器应用程序遍历其 Plugins 文件夹中的所有*.dll
文件,实例化每个文件并为每个文件调用上述 ReadConfig()
方法。当调用该函数时PluginMessaging_A.dll
一切都按预期工作,并且_pluginFile的值PluginMessaging_A.dll但是当 DLL 的第二个副本的 ReadConfig()
函数时,出于某种原因,PluginMessaging_B.dll
被调用,_pluginFile
再次解析为PluginMessaging_A.dll
内存中似乎有一些表在第一次实例化时记住GetType().Assembly
信息PluginMessaging.dll
,无论它在磁盘上具有什么物理名称,并为同一 DLL 的任何后续实例保留该信息,尽管磁盘上的名称不同。
似乎内存中有一些表可以记住 GetType((。PluginMessaging的程序集信息.dll第一次实例化时,无论它在磁盘上具有什么物理名称,并为同一DLL的任何后续实例保留该名称,尽管磁盘上的名称不同。
这一看法是正确的。文件名与程序集标识无关。
您认为您正在加载两个不同的程序集,但运行时确定您正在尝试再次加载同一程序集 - 并且不会加载它。
MSDN:程序集名称:
运行时在确定程序集的标识时不考虑文件名。程序集标识(由程序集名称、版本、区域性和强名称组成(必须对运行时清楚。
如果确实要从两个文件加载相同的程序集,则需要在单独的应用程序域中执行此操作。请参阅如何将包含所有引用的程序集递归加载到 AppDomain?。
或者,您可以更改名称、版本、区域性或强名称,然后再次重新编译:然后您将有两个不同的版本。
尝试
_pluginFile = System.IO.Path.GetFileName(GetType().Assembly.GetExecutingAssembly().Location);