user1015551
user1015551

Reputation: 197

C# making app support plugins, run multiple instances, possible?

Basically what I need is being able to add new functionality to my application, without updating the application itself.

Lets say I have an application with two plugins.

Application has a function called generateNumber();

Plugin_1 would have the following code:

void init(){ }

int exec(){
  int number = HOST_APPLICATION.generateNumber();
  number = number * 2;
  return number;
}

Plugin_2 would have the same structure, only different functionality:

void init(){ }

int exec(){
  int number = HOST_APPLICATION.generateNumber();
  number = (number * 10) + 13;
  return number;
}

I need multiple instances of each 'plugin' to run simultaneously (each in its own thread), so 20 threads total at the same time. The code would be something like this:

Main Application:

void init_plugins() { }

void execute_plugins(){
   for(int i=0; i<plugins.count; i++){

      for(int z=0; z<10; z++){
          Thread t = new Thread(plugin_research);
          t.start(plugins[i]);
      }

   }
}

void plugin_research(PluginStructure Plugin){
    Plugin.init();
    int return_val = Plugin.exec();
    // do something with return_val
}

I also need host application to call plugin's functions (the structure will be the same for all plugins) and plugin to be able to call host application's functions.

Each plugin would have different controls for configuration. I would need to show configuration in one place, but call plugin's functions multiple times simultaneously (using threads)

Is this possible? What would be the best way to accomplish this? can I do this with iPlugin?

Upvotes: 2

Views: 1088

Answers (4)

Marco
Marco

Reputation: 57573

Basicly each plugin should be derived from a base class exposing methods you want.

public abstract class BasePlugin
{
    protected int number;

    public abstract void init_plugin();
    public abstract int exec(int number);
    public BasePlugin(int number)
    {
        this.number = number;
    }
}

Then you have

public class Plugin1: BasePlugin
{
    public override void init_plugin()
    {
    }

    public override int exec(int number)
    {
    }
}

In your app you can create plugins and keep them in a list

List<BasePlugin> list = new List<BasePlugin>();
list.Add(new Plugin1(generateNumber()));
BasePlugin p2 = new Plugin2(generateNumber());
p2.init_plugin();
list.Add(p2);

and do with loaded plugins whatever you please.
Or (as I see from your edited question) you can create threads for every plugin...

To load plugins you could use functions like these:

public static List<T> GetFilePlugins<T>(string filename)
{
    List<T> ret = new List<T>();
    if (File.Exists(filename))
    {
        Type typeT = typeof(T);
        Assembly ass = Assembly.LoadFrom(filename);
        foreach (Type type in ass.GetTypes())
        {
            if (!type.IsClass || type.IsNotPublic) continue;
            if (typeT.IsAssignableFrom(type))
            {
                T plugin = (T)Activator.CreateInstance(type);
                ret.Add(plugin);
            }
        }
    }
    return ret;
}
public static List<T> GetDirectoryPlugins<T>(string dirname)
{
    List<T> ret = new List<T>();
    string[] dlls = Directory.GetFiles(dirname, "*.dll");
    foreach (string dll in dlls)
    {
        List<T> dll_plugins = GetFilePlugins<T>(Path.GetFullPath(dll));
        ret.AddRange(dll_plugins);
    }
    return ret;
}

Upvotes: 3

Alexei Levenkov
Alexei Levenkov

Reputation: 100547

Check out MEF - http://msdn.microsoft.com/en-us/library/dd460648.aspx. Even if you decide not to use it you can see how such architecture can be implemented and used.

Upvotes: 3

Daniel Mann
Daniel Mann

Reputation: 59020

Look into MEF, the Managed Extensibility Framework.

Upvotes: 2

Wayne Tanner
Wayne Tanner

Reputation: 1356

Look into MEF, the managed extensibility framework at http://mef.codeplex.com/. It has a lot of built in support for runtime discovery of plugin components.

Upvotes: 4

Related Questions