views:

127

answers:

2
public class MyPlugin : IPluginSystem
{
    [ExternalInput]
    public String myExternalProperty { get; set; }

    public bool execute()
    {
         if (myExternalProperty.Equals("My setter is called from elsewhere"))
             return true;
         return false;
    }
}

Is this possible? How would I achieve this? Would I need to specify typeof(X) also there in the attribute?

+1  A: 

Try looking at MEF (Managed Extensibility Framework) if you haven't. From the look of what you want to do, it's a perfect match.

Jimmy Chandra
Well, I am using MEF! MEF allows me to specify imports and exports, it doesn't let me propogate inputs to my parts, which can be made at runtime.
A: 

Sure, you'd just need something to bind those to a UI - I'll take an easy way out and assume a form with a single textbox. Depending on your requirements, a PropertyInfo grid or something may be more appropriate.

Something like:

class PluginUIBuilder {
    public void Fill(IPluginSystem p) {
       var t = ((object)p).GetType();
       foreach (var pi in t.GetProperties()) {
          if (pi.GetCustomAttributes(typeof(ExternalInput), true).Length > 0) {
             string value = Prompt(pi.Name);
             pi.SetValue(p, value, null);
          }
       }
    }

    string Prompt(string name) {
       using (var f = new InputForm()) {
          f.Prompt = "Enter a value for " + name;
          if (f.ShowDialog() = DialogResult.OK) {
             return f.Value;
          }
          return null;
       }
    }
}

// client code
var p = new MyPlugin();

var ui = new PluginUIBuilder();
ui.Fill(p);

p.Execute();

You'll probably want to add properties to your attribute for things like descriptions, a convert function or class (may want to leverage the builtin type converters), validation, etc.

At the end of the day, if you take this too far - you've just built the WinForm design surface. But, I've used Property Info grids for prompts for otherwise command line apps to decent success with very little code.

Mark Brackett
how would I do this, for things in other assemblies?
Basically, you just need the System.Type - so if you're dynamically loading the Assembly, then you can use Assembly.GetTypes(). If you're loading from a config file or something, then you can use Type.GetType(string). Etc, etc.
Mark Brackett