471,350 Members | 1,850 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

Delegates or events ?

GTi
[now with correct date and time]

I have this solution:

[File A - WIndows EXE] -> [File B - LIB DLL] -> [File C - Plugin DLLs]

A knows about B but not C
C knows about B but not A

Type A can be a EXE file or NT Service
There can be many of type A loaded but not necessarily the same file.

Type C is a plugin that is loaded by A on runtime.
There can be many of type C available but not necessarily the same file.

Now the problem.
A have a status window giving the end user status of the program.
The status is given by C.
So I think I must implement a interfaces in B and implment it into A and C.
C send statuses to B and use A as subscribber to events/delegates from B.

But I have problem understanding how this can be done.


Jan 9 '06 #1
4 1189
GTi wrote:
[now with correct date and time]

I have this solution:

[File A - WIndows EXE] -> [File B - LIB DLL] -> [File C - Plugin DLLs]

A knows about B but not C
C knows about B but not A

Type A can be a EXE file or NT Service
There can be many of type A loaded but not necessarily the same file.

Type C is a plugin that is loaded by A on runtime.
There can be many of type C available but not necessarily the same file.

Now the problem.
A have a status window giving the end user status of the program.
The status is given by C.
So I think I must implement a interfaces in B and implment it into A and C.
I don't think you'll need to implement the interface in A - A will just
*use* the interface, I suspect.
C send statuses to B and use A as subscribber to events/delegates from B.

But I have problem understanding how this can be done.


Well, you'll need a "custom" delegate in B if none of the ones in the
standard framework are suitable. Either way, your interface should
contain the event, so that A can subscribe to the events without
knowing the details of what the implementation is.

I'll try to write a quick sample later on, if that would help.

Jon

Jan 9 '06 #2
GTi
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
GTi wrote:
[now with correct date and time]

I have this solution:

[File A - WIndows EXE] -> [File B - LIB DLL] -> [File C - Plugin DLLs]

A knows about B but not C
C knows about B but not A

Type A can be a EXE file or NT Service
There can be many of type A loaded but not necessarily the same file.

Type C is a plugin that is loaded by A on runtime.
There can be many of type C available but not necessarily the same file.

Now the problem.
A have a status window giving the end user status of the program.
The status is given by C.
So I think I must implement a interfaces in B and implment it into A and
C.


I don't think you'll need to implement the interface in A - A will just
*use* the interface, I suspect.
C send statuses to B and use A as subscribber to events/delegates from B.

But I have problem understanding how this can be done.


Well, you'll need a "custom" delegate in B if none of the ones in the
standard framework are suitable. Either way, your interface should
contain the event, so that A can subscribe to the events without
knowing the details of what the implementation is.

I'll try to write a quick sample later on, if that would help.

Jon


Jon,
I can't wait for a quick sample.
Maybe I can then understand the missing bit.
Jan 9 '06 #3
Hi,

A knows about B but not C
C knows about B but not A
This is correct, in B you will declare the interfaces that both A & C will
implement/use
Type A can be a EXE file or NT Service Does not matter, except that the service cannot have a console window
There can be many of type A loaded but not necessarily the same file.
Not clear of what this means, are you refering that you may load several
instances of A (under different service names I assume) or you mean that
there several projects that conform to A description?

Type C is a plugin that is loaded by A on runtime.
There can be many of type C available but not necessarily the same file.
Not a problem, you load the DLL dynamically and handle the instance using
the interfaces declared in B , see Jon's plugin article.
Now the problem.
A have a status window giving the end user status of the program.
Note that a service should not have interaction with the desktop, so in this
case is better to use the eventlog
The status is given by C.
So I think I must implement a interfaces in B and implment it into A and
C.
C send statuses to B and use A as subscribber to events/delegates from B.


No really, You declare an interface in B , C has a class that implement this
interface and you use it from A.

Here I wrote how it may looks like, note that I wrote it here so it WILL
NOT compile for sure !!!
But I hopoe you will get the idea of how it's done.

Like:
IN B
interface ILog {
EventHandler event GotNewNotif;
public string theNotif;
}

IN C:
Public class theClass: ILog{
public EventHandler event GotNewNotif ;
public string theNotif;

private void SendNotif()
{
theNotif = " sdfas fas fawqr qwr";
GotNewNotif( this, null);
}
}
In A:
class Class
{
void GotMotif( object sender, EventArgs e)
{
Console.Write( ((ILog)sender).theNotif );
}

void WireAll()
{

Assemble a = Assembly.LoadFromFile(
Configuration.AppSettings["c_file_source"] );
ILog l = (ILog) a.CreateInstance(
Configuration.AppSettings["what_class_to_create"] );
l.GotNewNotif += new EventHandler( GotNotif);
}
}


--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
Jan 9 '06 #4
GTi <tu****@gmail.com> wrote:
I can't wait for a quick sample.
Maybe I can then understand the missing bit.


Okay, here it is:

A.cs: (The "driver" class)
using System.Reflection;

public class MainApp
{
static void Main(string[] args)
{
foreach (string x in args)
{
Assembly assm = Assembly.Load(x);

foreach (Type t in assm.GetTypes())
{
if (typeof(IPlugin).IsAssignableFrom(t))
{
IPlugin plugin=(IPlugin)Activator.CreateInstance(t);
plugin.Notification += new EventHandler(WriteArgs);
plugin.Start();
}
}
}
}

static void WriteArgs(object sender, EventArgs e)
{
Console.WriteLine (e.ToString());
}
}

B.cs: (The interface)
using System;

public interface IPlugin
{
event EventHandler Notification;

void Start();
}

C.cs: (The plugins)
using System;
using System.Threading;

// Plugin1 fires the notification event once a second for
// 10 seconds
public class Plugin1 : IPlugin
{
// Using field-like events for simplicity
public event EventHandler Notification;

public void Start()
{
new Thread(new ThreadStart(ThreadEntry)).Start();
}

void ThreadEntry()
{
for (int i=0; i < 10; i++)
{
Notification(this, new NamedArg("Plugin1"));
Thread.Sleep (1000);
}
}
}

// Plugin2 just fires the notification event once
// and stops
public class Plugin2 : IPlugin
{
// Using field-like events for simplicity
public event EventHandler Notification;

public void Start()
{
Notification(this, new NamedArg("Plugin2"));
}
}

class NamedArg : EventArgs
{
string name;

internal NamedArg (string name)
{
this.name = name;
}

public override string ToString()
{
return name;
}
}

Compiling from the command line:
csc /target:library B.cs
csc /target:library C.cs /r:B.dll
csc A.cs /r:B.dll

Then run it with
A.exe C

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 9 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by STom | last post: by
3 posts views Thread by Chua Wen Ching | last post: by
7 posts views Thread by Peter Larsen [] | last post: by
5 posts views Thread by studio60podcast | last post: by
reply views Thread by XIAOLAOHU | last post: by

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.