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 IInterfacePlugi n
{
// uses the connection string to establish a connection
public void Create( string connectionStrin g );
// 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"
IInterfacePlugi n 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 : IInterfacePlugi n
{
string databaseConnect ionString = "";
public void Create ( string connectionStrin g )
{
databaseConnect ionString = connectionStrin g;
}
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 : IInterfacePlugi n
{
// 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.