473,320 Members | 2,035 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Need help on Raising Events on Remote Objects

I'm coding a project using the following article as reference:

http://www.codeproject.com/csharp/Dy...ginManager.asp

In this type of project, plugins are loaded dynamically into a Plugin
Manager.

Your main application then hooks into the Plugin Manager.

What I'm trying to figure out is how to impliment some form of raising
events from the Plugins, that in turn surface all the way to the main
application.

Since the plugins are loaded assemblies into a secondary application
domain, I'm not sure how to go about this.
Any ideas, feedback or opinions welcomed.

--Riggs

Nov 16 '05 #1
7 2420
Riggs,

this would occur in the same way as normal events are handled...
For a very basic and generic event you'd do something like this in your
plugin class:

public event EventHandler RingTheBell;

void SomeMethod()
{
// do something here

// now ring the bell
RingTheBell(this, new EventArgs() );
}
Then in the main section have something like this

object LoadLibrary ( string pluginFilename, string nameSpace, string
className )
{
try
{
Assembly assmObj = Assembly.LoadFrom( pluginFilename );
return assmObj.CreateInstance ( nameSpace + "." + className,
true );
}
catch ( Exception )
{
return null;
}
}

void LoadPlugin()
{
// create a plugin object
object pluginObj = LoadLibrary ( @"c:\myPlugin.Dll",
"Company.Project.Module", "myPlugin" );
if ( pluginObj == null ) return;

IPlugin plugin = (IPlugin)pluginObj;
plugin.RingTheBell += new EventHandler ( OnBellRing );
}

void OnBellRing ( object sender, EventArgs e )
{
// do something now you know the plug in has rung the bell...
}
If you want to pass data from the plug in to the event handler in your main
section then you need to declare a delegate to do this. Google on delegates
and events to find out how to do this. I'm not sure the interface can hold
event and delegates, so you may have to use an abstract class instead.

Thanks.

Daniel.
<ci******@hotmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
I'm coding a project using the following article as reference:

http://www.codeproject.com/csharp/Dy...ginManager.asp

In this type of project, plugins are loaded dynamically into a Plugin
Manager.

Your main application then hooks into the Plugin Manager.

What I'm trying to figure out is how to impliment some form of raising
events from the Plugins, that in turn surface all the way to the main
application.

Since the plugins are loaded assemblies into a secondary application
domain, I'm not sure how to go about this.
Any ideas, feedback or opinions welcomed.

--Riggs

Nov 16 '05 #2
If you impliment the interface and reference the libraries in your
Solution Explorer, your technique would work fine--I think.

However, the libraries are loaded dynamically and therefore have no
hook into the Plugin structure to create an EventHandler from.

A Plugin Manager handles the loading and unloading of assemblies in an
Application Domain. This is done so you can dynamically update
libraries on the fly without ever having to stop your main application.

Methods are accessed by scanning the assembly for MarshalByRefObject
types, and then Instances are Created to call the methods with whatever
parameters are defined.

If I directly impliment an interface within the project, I can never
dynamically update them on the fly when the application is running.

Unless I simply don't understand something about your solution, which
could very well be the case. =)

I'm actually toying around with using delegates right now, in an
attempt to find a solution--thanks for the feedback though.

Nov 16 '05 #3
My apologies, I've just read the article a little closer... and I see we're
coming from two different areas.

Could you describe, briefly, what it is your solution requires in regards to
the plug-ins and why you choose the Plug-in Manager?
If it's simply because you can unload assemblies for example, then this can
be worked around with Load if you really want to with a simple assembly
wrapper.
How do you require the application to update itself with regards to the
plug-ins?
<ci******@hotmail.com> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
If you impliment the interface and reference the libraries in your
Solution Explorer, your technique would work fine--I think.

However, the libraries are loaded dynamically and therefore have no
hook into the Plugin structure to create an EventHandler from.

A Plugin Manager handles the loading and unloading of assemblies in an
Application Domain. This is done so you can dynamically update
libraries on the fly without ever having to stop your main application.

Methods are accessed by scanning the assembly for MarshalByRefObject
types, and then Instances are Created to call the methods with whatever
parameters are defined.

If I directly impliment an interface within the project, I can never
dynamically update them on the fly when the application is running.

Unless I simply don't understand something about your solution, which
could very well be the case. =)

I'm actually toying around with using delegates right now, in an
attempt to find a solution--thanks for the feedback though.

Nov 16 '05 #4
I was opting to go with a Plug-in Manager for a distributed application
system. We have an existing system that is made up of multiple Window
Services (somewhere in the neighborhood of 40+). We probably process
over 300k files a day in the system.

Rather than stop each one and update whatever is needed (causing files
to backlog) and then restart them all I was thinking of integrating an
auto-update type of mechanism where I could maintain 1 master folder,
drop off the update and a distribution system would then copy the
file(s) to whatever Server(s) they need to be deployed to.

In building a system like this, one PlugIn might depend on another and
therefore I need some way to propegate data and requests up to the main
application (Window Service) that then sends it down to the desired
Plugin. In the event of a database type plugin, after getting a
recordset request, I'll need to return the resultset to the requesting
plugin.

I was thinking of raising events with the data to be transferred
between each plugin, letting the main application shuffle the requests.

The Plugin Manager is currently custom to the plugin's to some degree,
so the only time I would stop the Window Service (main application) is
when I would need to distribute a new update to the manager.

I suppose I could always incorporate the database type plugin much the
same way the plugins are hooked into the manager, except just extend it
down below the plugin that requires database calls--using a modified
type of plugin manager just to load the database plugin. Not sure if
that would be the most efficient, but it would probably work.

Was looking at breaking down the core components into separate plugins,
so business logic would reside in 1, database in a separate, etc. etc.

Nov 16 '05 #5
To branch off a litte...

It sounds to me like you're writing a message pump type application?
One plug-in, for example, only knows about accessing and reading from a
database.
Another, determines what should happen to this data, and how it should be
routed.
Then there are other plug-in's that are responsible for posting data to
their respective mediums. It may be a file, message queue, database etc.

am I way off here or not?
if not, I've written something that does just this, it handles hundreds of
megabytes an hour with the only restriction being the system on which it is
run.
Back to the main problem... The fact you want events to occur across
plug-in's suggests the design could be improved. For example, once data is
read from a plugin why not have the reader thread pass back the data to the
core, who is then responsible for distributing the data to other plug-in's
synchronously or asynchronously.
If you still feel I'm missing the mark, please explain, in basic terms, what
your application does (and not how it does it).

Thanks.

Dan.

<ci******@hotmail.com> wrote in message
news:11**********************@c13g2000cwb.googlegr oups.com...
I was opting to go with a Plug-in Manager for a distributed application
system. We have an existing system that is made up of multiple Window
Services (somewhere in the neighborhood of 40+). We probably process
over 300k files a day in the system.

Rather than stop each one and update whatever is needed (causing files
to backlog) and then restart them all I was thinking of integrating an
auto-update type of mechanism where I could maintain 1 master folder,
drop off the update and a distribution system would then copy the
file(s) to whatever Server(s) they need to be deployed to.

In building a system like this, one PlugIn might depend on another and
therefore I need some way to propegate data and requests up to the main
application (Window Service) that then sends it down to the desired
Plugin. In the event of a database type plugin, after getting a
recordset request, I'll need to return the resultset to the requesting
plugin.

I was thinking of raising events with the data to be transferred
between each plugin, letting the main application shuffle the requests.

The Plugin Manager is currently custom to the plugin's to some degree,
so the only time I would stop the Window Service (main application) is
when I would need to distribute a new update to the manager.

I suppose I could always incorporate the database type plugin much the
same way the plugins are hooked into the manager, except just extend it
down below the plugin that requires database calls--using a modified
type of plugin manager just to load the database plugin. Not sure if
that would be the most efficient, but it would probably work.

Was looking at breaking down the core components into separate plugins,
so business logic would reside in 1, database in a separate, etc. etc.

Nov 16 '05 #6
There isn't just one application, there are 40+ of them. Each has it's
own unique function. Some route files, some FTP, some Email, some
interface with a Fax Manager, some do file format conversions, others
update databases, etc.

In your example, the reader thread (let's call this Plugin A) pass back
the data to the core, who is then responsible for distributing the data
to other plug-in's (let's just use 1 for simplicity, Plugin B).

So we have the initial layout:

Window Service
- Core
- Core Plugin : Plugin A
- Core Plugin : Plugin B

If these were all integrated directly into the project, it's pretty
easy to do what you're suggesting by having the Core responsible for
distribution of tasks.

However, because these are dynamically loaded they all use a generic
interface. If you code specific to the PlugIn in the Core, all Plugins
are going to require that type of interface. Example, it doesn't make
sense to institute a database recordset method on a Plugin that does
nothing more than move files.

To get around this, I was considering raising events (only thing I
could think of) to which the Core would then handle as it needs
to--however I can't figure out how to raise events in dynamically
loaded assemblies.

I started looking into remote delegate objects, and I believe I'm
pretty close to a solution.

I'm totally open to ideas or suggestions though.

The goal I have in mind is to unify as much of the code as I can for
all Window Service applications we use, through the use of Plugins
which can be loaded dynamically on the fly so the Window Services
themself would rarely, if ever, need to be stopped for any reason other
than a Server reboot.

Nov 16 '05 #7

This doesn't really make sense to me
However, because these are dynamically loaded they all use a generic
interface. If you code specific to the PlugIn in the Core, all Plugins
are going to require that type of interface. Example, it doesn't make
sense to institute a database recordset method on a Plugin that does
nothing more than move files.


The core knows this:
- where the inbound interfaces are
- where the outbound interfaces are
- how the messages from each inbound interface are routed to one, or many
outbound interfaces

The plug in knows
- some connection string the core has passed it. This may be a path, a
database connection string, message queue address, ftp server/UID/password
- how to use the connection string to establish a connection to whatever it
is it connects to
- [inbound] how to, once a connection is established, "listen" / "read" /
"poll for" message data
- [outbound] how to, once a connection is established, "send" / "poke" the
data

Surely then you'd establish one interface that is something like this:

// knows nothing of databases, files, etc etc...
interface IInterfacePlugin
{
// uses the connection string to establish a connection
public void Create( string connectionString );

// listens to the interface
public string Listen();

// sends the data to the interface
public void Send( string dataToSend );
}

Okay, from here we know that every "interface" plug-in "IS A"
IInterfacePlugin according to our basic OOD rules. We also know that we can
create a class library that only contains this interface, and that we can
then create subsequent plug-ins that derive from this interface, and hence
can be late binded to by the core.

Then we'd have a SqlClientPlugin.Dll that pulls messages off a database with
something like this:

using // anything database
class SqlClientPlugin : IInterfacePlugin
{
string databaseConnectionString = "";

public void Create ( string connectionString )
{
databaseConnectionString = connectionString;
}

public string Listen()
{
// establish a connection with SqlConnection

// check for data

// return this data
}

// send and other code

}

Now we could have a FilePlugin.Dll which also inherits from the interface
like this

class File : IInterfacePlugin
{
// code here that knows nothing of databases or anything else
// but uses the connection string to decide what path to check
// out, and passes that data back through string Listen()
}

The basic windows service core algorithm would be:
[OnStartup]
load up the interfaces
for each inbound interface configured
create a thread and call "watch interface" on this interface

[OnShutdown]
foreach thread that is open
shut it down

[Load Up The Interfaces]
foreach configured inbound interface
load a plugin object and store in a cache
foreach configured outbound interface
load a plugin object and store in a cache

[Watch Interface] (as used in Startup)
while we're listening for new data
data <-- listen to my inbound interface
decide where this data should be sent to
foreach outbound interface that should receive this data
send the data to the outbound interface
This then means one application controls everything. It's one service, with
many threads, checking many things out at once. This architecture allows you
to check hundreds of different interfaces at one time. If you need to change
an interface, rebuild it, stop the one service, drop it in the directory
where the plugin's are, and restart the service.

With your approach, what if the core is working with the plugin when you
attempt to update it?
Replacing the copy won't work since the file is in use and locked, so you'd
have to restart the service anyway?

What I've given you here is the basic building block of a system that's
being distributed across the UK, Europe and even over to the far east this
year. Heck it probably was involved in the process of that coffe you drank
this morning. ;o)

Good luck with your project.
Nov 16 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: serge calderara | last post by:
Dear all, I have a class wich is raising events as normally it should do. having a form in the same assembly wich is catching those events works fne. Raise events gets catch normaly within the...
3
by: James Dunkerley | last post by:
Hi, I am trying to create a class which downloads a web page in the background and then raises an event in the original thread in which it was created. This class is going to be the basis of a...
6
by: Dan | last post by:
I've created a pocketpc app which has a startup form containing a listview. The form creates an object which in turn creates a System.Threading.Timer. It keeps track of the Timer state using a...
0
by: Greg Park | last post by:
I have many user controls loading into a web page using Page.LoadControl However, I'm unable to figure out how to raise an event when a button is click or a check box is checked. I can have...
0
by: Joe Campbell | last post by:
I am encountering a problem raising WMI events from an asp.net application. The error received (as captured in the event log) is as follows: System.Runtime.InteropServices.COMException...
3
by: Franky | last post by:
IN vb.Net Class clsCommande Inherits CollectionBase and Class clsProduct clsCommand contain a IList of clsProduct
3
by: Ben R. | last post by:
Hi there. I'm referring to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconraisingmultipleevents.asp The article implies that rather than having one field...
2
by: Gman | last post by:
Hi, I have created a usercontrol, a grid control essentially. Within it I have a class: clsGridRecord. I have coded the events such that when a user clicks on the grid, say, the events occur on...
0
by: Apu Nahasapeemapetilon | last post by:
Suggestions on cross-posting this issue would be appreciated. I've got a C# .NET DLL (CLR v1.1) that raises events into its container. When the container is a .NET application, raising the...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.