2

I am trying to implement a plugin system in C#, and for that I created the following classes and interfaces:

Included in both loader and plugin:

interface IDevicePlugin {
    string GetName();
    string GetVersion();
}

Plugin code (compiles to .dll)

public class DummyPlugin : IDevicePlugin {
        protected string name;
        protected string version;

        public string GetName() {
            return name;
        }
        public string GetVersion() {
            return version;
        }
  }

The code to load the plugin is as follows:

IDevicePlugin thePlugin;
Assembly plugin = Assembly.LoadFrom("plugin.dll");

foreach (Type pluginType in plugin.GetTypes()) {
       if (pluginType.IsPublic && !pluginType.IsAbstract) {
            Type typeInterface = pluginType.GetInterface("IDevicePlugin", true);
            if (typeInterface != null) {
                 // the plugin implements our IDevicePlugin interface
                 thePlugin =  (IDevicePlugin)Activator.
                         CreateInstance(plugin.GetType(pluginType.ToString()));
            }
       }
}

And this crashes with:

Unable to cast object of type 'PluginTest.DummyPlugin' to type 'PluginTest.IDevicePlugin'.
Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
  • 3
    *"Included in both loader and plugin"* - To be clear, this interface is defined twice? And each version (the plugin and the loader) is compiled against the separate definition? – David Aug 31 '12 at 12:42
  • It is not defined twice. It is defined in the loader project, and the plugin project (in Visual Studio 2010) has a reference to the .cs file that defines it. – Bart Friederichs Aug 31 '12 at 12:43
  • This may have been answered previously in http://stackoverflow.com/questions/1596796/net-unable-to-cast-object-to-interface-it-implements. – akton Aug 31 '12 at 12:45
  • Doesn't that create a circular reference problem? Your loader project is low loading a class from a plugin project that references the loader project? – pdriegen Aug 31 '12 at 12:45
  • No, the loader project loads a .dll from the filesystem. The plugin project loads a .cs file from the loader project to build the .dll. – Bart Friederichs Aug 31 '12 at 12:46
  • Because you are compiling it into two different assemblies the interfaces are distinct types...so not the same....even though the same name. – Colin Smith Aug 31 '12 at 12:48

1 Answers1

8

The interface exists twice:
Once in your plugin.dll and once in your loader.
The reason is that you added a reference (=link) to the *.cs file containing the interface definition to the plugin project. Additionally, the same *.cs file is part of the loader project.
Because of that, the interface gets compiled into both assemblies. These are two different interfaces, even when they are named the same!

To fix this problem, you should do the following:

Either add a reference for the Loader project to the plugin project
- OR -
Create a new project for the interface and reference this project from both the loader and the plugin projects.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443