0

i want to use plugins to extend my c# wpf application. i've made a simple interface, then a plugin dll, then a test class to load the plugin. the plugin load properly and i can get a list of its properties.

the inteface:

public interface IStrat
{
    string Name { get; }
    void Init();
    void Close(int dat);
}

the plugin:

 public class Class1 : IStrat
{
    public string info;

    [Input("Info")]
    public string Info
    {
        get
        {
            return info;
        }

        set
        {
            info = value;
        }
    }

    public string Name
    {
        get { return "Test Strategy 1"; }
    }

    public void Init()
    {

    }

    public void Close(int dat)
    {

    }
}

the test class:

class test
{
    public void getPlugins()
    {
        Assembly myDll = Assembly.LoadFrom(Class1.dll);
        var plugIn = myDll.GetTypes();

        List<string> temp = new List<string>();

        //gets the properties with "input" attribute, it returns the Info property fine
        var props = item.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(Input)));
        foreach (var prop in props)
        {
            temp.Add(prop.Name + " (" + prop.PropertyType.Name + ")");// returns Info (string)
        }
        stratFields.Add(item.Name, temp);// stratFields is a dictionary that keeps the name of the plugin as key and a list of properties names as value
    }

    public void create()
    {
        //create an instance of my plugin
        Type t = plugIn[0];
        var myPlugin = (IStrat)Activator.CreateInstance(t);

        myPlugin.Init(); // this works, i can access the methods
        myPlugin.Info = "test"; //this doesn't work
    }            
}

i want to access the "Info" property to get/set it for that specific instance. when i use the getproperties() method it finds it, so there must be a way to use it.

different plugins have different number and type of properties.

1 Answers1

0

Since Info property is not part of the interface you have to use reflection (Set object property using reflection) or dynamic:

 myPlugin.Init(); // this works because IStrat has Init method
 dynamic plugin = myPlugin;
 plugin.Info = "test"; // this works because `Info` is public property and 
                       // dynamic will perform late (run-time) binding.

Better approach would be add all necessary methods to the interface.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • using dynamic works if i know in advance the name of the property that will be in the plugin, so i cannot hardcode "plugin.Info". i would need something like (plugin."passPropertyNameAsAString") – tubular2000 Jan 08 '16 at 14:57
  • @tubular2000 I'm not sure why reflection suggestion is not enough for your purposes - you may want to clarify that in your question. – Alexei Levenkov Jan 08 '16 at 16:52
  • i'm accepting this answer for pointing me to reflexion. as an added bonus i can set my properties and convert type in a single line of code with "convert.changeType". i can't add everything to the interface because different plugins have different functionality and different number/type of properties. – tubular2000 Jan 08 '16 at 18:41