2

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?

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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;
}

6 Comments

Thanks Marco! Can you tell me when I start new project in C#, what should I choose, Win Application for plugin? I need Gui too for configuration. Each plugin will have its own configuration.
@user1015551: for every plugin you can choose Windown Form; then in project properties goto Application tab and select "Class library" as output type
@user1015551: as you can see from my code, don't call HOST_APPLICATION.generateNumber(); from plugins, but pass a new generated number to each plugin with its constructor. This way you split plugins from your app.. otherwise which is the reason to have separate plugins?
Thanks! One more question. what functions do I use to load the library (plugin) from main application? can I create a gui for class library? or should my plugin access main application form and generate gui by code?
The reason I want to call generateNumber() from plugin is that generateNumber() is actually going to be http wrapper class, that way I could track running threads, network usage etc.. in main application. is that a bad way to do this?
|
3

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.

Comments

2

Look into MEF, the Managed Extensibility Framework.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.