|
-
Jun 27th, 2006, 10:45 AM
#1
Thread Starter
PowerPoster
[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
-
Jun 27th, 2006, 02:40 PM
#2
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.
-
Jun 27th, 2006, 02:46 PM
#3
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.
-
Jun 27th, 2006, 02:59 PM
#4
Thread Starter
PowerPoster
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!
-
Jun 27th, 2006, 04:41 PM
#5
Thread Starter
PowerPoster
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?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|