Results 1 to 5 of 5

Thread: [1.0/1.1] implementing plugins

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    [1.0/1.1] implementing plugins

    Hi.
    I have a C# .NET 1.1 application, and may wish to implement plugins.

    I understand we create a class library which is an interface, so other developers can inherit this.

    an interface is a "must have" set of signatures (term) which are to be included in the developers plugin.

    question here:

    can an interface have events/delegates?


    Moving on, within my application, if for example the question above is true, within my application how would I raise the event? (I know how to raise events I believe but not sure if it would work the same way?)

    If we have say 2 plug ins, I want these plugins to have implemented an event from the interface, how would I raise this event within my application so these 2 plugins would be notified of the event?



    And finally, how would you instantiate plugins (of a certain interface type) and access them?

    Many thanks

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  2. #2
    PowerPoster sunburnt's Avatar
    Join Date
    Feb 2001
    Location
    Boulder, Colorado
    Posts
    1,403

    Re: [1.0/1.1] implementing plugins

    Generally, you will have three projects.

    A shared library (dll) which defines an IPlugin interface and a Host class/interface.

    Your main application (exe).

    At least one plugin (dll).

    Both the plugin and main application will require references to the shared library.


    Here are three files, which you can use to generate a sample project. The project will try to load every class which implements IPlugin from every *.dll in the application directory.

    It will read a line of input, and pass this input to each loaded plugin, which can then write a response back to the user. The current plugin will echo whatever you type, and close the program if you type "exit".


    PS - I tried not to knowingly use an 2.0 functionality, but I might have unwittingly!


    Program.cs - compile to PluginExample.exe
    Code:
    using System;
    using System.Collections;
    using System.Text;
    using System.IO;
    using System.Reflection;
    
    namespace PluginExample
    {
        class Program
        {
            static ArrayList plugins = new ArrayList();
            static PluginShare.Host host = new PluginShare.Host();
    
            static void LoadPlugins()
            {
                string[] files = Directory.GetFiles(Environment.CurrentDirectory, "*.dll");
    
                foreach (string file in files)
                {
                    try
                    {
                        Assembly asm = Assembly.LoadFile(file);
                        foreach (Type type in asm.GetTypes())
                        {
                            // if the type implements IPlugin
                            if (type.GetInterface("IPlugin") != null)
                            {
                                // create an instance of the class
                                PluginShare.IPlugin newPlugin = (PluginShare.IPlugin)Activator.CreateInstance(type);
                                // pass it our host object so we can communicate
                                if (newPlugin.Initialize(host))
                                {
                                    plugins.Add(newPlugin);
                                    Console.WriteLine("Loaded Plugin: {0}", newPlugin.Name());
                                }
                                else
                                    Console.WriteLine("Failed to load plugin: {0}", newPlugin.Name());
                            }
                        }
    
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            
            static void Main(string[] args)
            {
                LoadPlugins();
                host.Running = true;
    
                while (host.Running)
                {
                    Console.Write("> ");
                    host.ReadLine();
                }
            }
        }
    }

    IPlugin.cs - compile to PluginShare.dll
    Code:
    using System;
    using System.Text;
    
    namespace PluginShare
    {
        public delegate void UserInputDelegate(string message);
    
        // this class can implement functionality to allow the 
        // plugin to communicate back to the main application,
        // or register events.
        public class Host
        {
            public bool Running = true;
    
            public event UserInputDelegate InputEvent;
    
            
            public void WriteLine(string msg)
            {
                Console.WriteLine("Plugin: {0}", msg);
            }
    
            public string ReadLine()
            {
                string s = Console.ReadLine();
    
                if (InputEvent != null)
                    InputEvent(s);
    
                return s;
            }
        }
     
        public interface IPlugin
        {
            string Name();
            bool Initialize(Host host);
            bool Shutdown();
        }
    }
    TestPlugin.cs - compile to TestPlugin.dll
    Code:
    using System;
    using System.Text;
    
    namespace TestPlugin
    {
        public class TestPlugin : PluginShare.IPlugin
        {
            private PluginShare.Host h;
            #region IPlugin Members
    
            public string Name()
            {
                return "TestPlugin 1.0";
            }
    
            public bool Initialize(PluginShare.Host host)
            {
                h = host;
                h.InputEvent += new PluginShare.UserInputDelegate(h_TestEvent);
                return true;
            }
    
            void h_TestEvent(string message)
            {
                h.WriteLine("Your message was: " + message);
                if (message == "exit")
                {
                    h.WriteLine("Shutting down!");
                    h.Running = false;
                }
    
            }
            public bool Shutdown()
            {
                h.InputEvent -= new PluginShare.UserInputDelegate(h_TestEvent);
                return true;
            }
            #endregion
        }
    }
    Last edited by sunburnt; Jun 27th, 2006 at 02:43 PM.
    Every passing hour brings the Solar System forty-three thousand miles closer to Globular Cluster M13 in Hercules -- and still there are some misfits who insist that there is no such thing as progress.

  3. #3
    PowerPoster sunburnt's Avatar
    Join Date
    Feb 2001
    Location
    Boulder, Colorado
    Posts
    1,403

    Re: [1.0/1.1] implementing plugins

    With regards to your question about delegates, I think this approach might be what you're looking for:

    Using the IPlugin interface, force all plugins to implement a function called "void OnSomeEvent(string message)"

    Our application class can have an event, "SomeEvent", with a delegate signature matching the OnSomeEvent function above.

    When we load each plugin, perform the following action:

    Code:
    thisApplication.SomeEvent += new SomeEventDelegate(thisPlugin.OnSomeEvent);
    Now, when we perform the action:

    Code:
    if (SomeEvent != null)
       SomeEvent("event!!");
    each plugin's OnSomeEvent function will be called.

    Hope this helps!
    Every passing hour brings the Solar System forty-three thousand miles closer to Globular Cluster M13 in Hercules -- and still there are some misfits who insist that there is no such thing as progress.

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: [1.0/1.1] implementing plugins

    Wow, you are amazing! I greatly appreciate this and has been most helpful.

    I cant wait to experiment.

    Thank-you so much! You rule!

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: [1.0/1.1] implementing plugins

    I'm having a try at this now, once again I am finding it hard to grasp events/delegates.

    Could you explain to me how would I implement an event in my Main Application, which will also instantiate these events in the plugins?

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width