问题
I've written a pluggable application that loads plugins as assemblies. Each plugin reads an XML configuration file which basically has different string settings.
Everything works fine with different plugins, but I'm experiencing strange behavior when I copy and paste an existing plugin assembly dll (but change it's XML configuration).
Plugin A |- PluginA.dll
|- PluginA.xml
Plugin B |- PluginB.dll
|- PluginB.xml
The original assembly (A) and copied assembly (B) are loaded, but it seems that that the application has loaded the exact same plugin (B) twice.
I know this because the plugin interface has a property called 'ApplicationName' and the value is read from the XML file in the appropriate plugin. The XML file is being read for each plugin correctly, and the property values are supposed to be 'A' and 'B', respectively.
foreach (var pluginFile in LoadedPluginFiles) // 2 different plugin filenames
{
LogMessage("Loading plugin: " + pluginFile); // correct filename in loop
ObjectHandle oHandle = Activator.CreateInstanceFrom(pluginFile, "MailboxMonitorPlugin.MailboxMonitorPlugin");
MailboxMonitorPlugin.IMailboxMonitorPlugin pluginInfo = oHandle.Unwrap() as IMailboxMonitorPlugin;
pluginInfo.Initialize(MailLink.Service.Properties.Settings.Default.PluginsPath);
LogMessage("Plugin Application Name: " + pluginInfo.ApplicationName.ToString()); // Same application name (B) even though different file loaded in the loop.
After I load the plugins, I write the property names out to the log, and the plugin has it's property read twice.
Is there a low-level operation happening here that I don't understand? Perhaps a pointer to the same assembly because they're exactly the same objects?
回答1:
You use Activator.CreateInstanceFrom call. Internally, it will call Assembly.LoadFrom. If you read documentation for Assembly.LoadFrom, you will see:
If an assembly with the same identity is already loaded, LoadFrom returns the loaded assembly even if a different path was specified.
So after you loaded first copy of your assembly, all subsequent loads of the same assembly, no matter the path, will return first assembly. This also means that Assembly.CodeBase property (which you most likely use to get path to your xml configuration file) will return path to the first loaded assembly too, hence your problem.
来源:https://stackoverflow.com/questions/32560521/dynamically-loading-different-assemblies-that-are-copies-of-each-other