1

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?

Michael
  • 57,169
  • 9
  • 80
  • 125
Daniel Minnaar
  • 5,865
  • 5
  • 31
  • 52
  • Consider using ProcMon (https://technet.microsoft.com/en-us/library/bb896645.aspx) to diagnose if the file is being hit at all. I've noticed some strange behavior before with app-domains. – WHol Sep 14 '15 at 08:50

1 Answers1

0

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.

Evk
  • 98,527
  • 8
  • 141
  • 191
  • Well since you have path to plugin dll, you also have path to correct config xml. You can pass that path to your plugin explicitly (i.e. plugin.Initialize(pathToConfig, ). So in your case it is not necessary to load duplicate assemblies to memory at all. – Evk Sep 14 '15 at 10:01