473,396 Members | 1,755 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,396 software developers and data experts.

modular application

Hi!

I mentioned this in my other post today but at that time I though I had it
all figured out. When
I got a reply regarding my other questing I saw that I don't :)

Here's my problem:

I would like to have an application where I would write the core and the
users could write
their own addins for the application.
Even the basic features I would provide would be addins.

Here's my idea: Create a basic form, which would contain the ModuleLoader
class. That class
would read the modules.xml file and dynamiclly load all the modules.
All the modules would have to implement the interface IModule, plus
IModuleMenu if the module
would add something to the menubar.
Here comes the tricky part...
Some of the modules could provide some services. Let's say I have a module,
which communicates with
a GPS device and provides the service GPS. Another module would display a
map based on the GPS location. How would the module Map get the location
from another module?
The module could "ask" the ModuleLoader to point to the module, which
provides the service "GPS" but
I still don't have an idea as how to get the information from the module. I
could require that
if the module provides GPS service that he must have public properties:
X,Y,Z...

Another problem is module execution. Do I give each module it's own
execution thread?
Or perhaps just the ones that provide services?

Any ideas would REALLY help...
saso
Nov 15 '05 #1
7 1568
Here's what I do in a situation that is very similar to yours. My plugins
(or modules as you call them) implement interface IPlugin, and the shell
application that loads the plugins implements interface IHost. When the host
loads a plugin it gives a reference to IHost to the plugin.

One of the methods in IHost is declared like so:

IPLugin GetPlugin(Type t);

In the implementation of this method, the host goes over all loaded plugins
and returns a reference to the first plugin that implements type 't'.

Applying this approach to your case, in order to obtain a reference to the
GPS plugin and to get the location, your Map plugin would something similar
to this:

IPlugin plugin = ihost.GetPlugin(typeof(IGpsPlugin));
IGpsPlugin gpsPlugin = (IGpsPlugin)plugin;
Location loc = gpsPlugin.Location;

This approach works for me just fine. Depending on your particular needs you
might want to tweak the logic, but anyway this is the big picture.

Regards,
Sami

"Saso Zagoranski" <sa*************@guest.arnes.si> wrote in message
news:bv**********@planja.arnes.si...
Hi!

I mentioned this in my other post today but at that time I though I had it
all figured out. When
I got a reply regarding my other questing I saw that I don't :)

Here's my problem:

I would like to have an application where I would write the core and the
users could write
their own addins for the application.
Even the basic features I would provide would be addins.

Here's my idea: Create a basic form, which would contain the ModuleLoader
class. That class
would read the modules.xml file and dynamiclly load all the modules.
All the modules would have to implement the interface IModule, plus
IModuleMenu if the module
would add something to the menubar.
Here comes the tricky part...
Some of the modules could provide some services. Let's say I have a module, which communicates with
a GPS device and provides the service GPS. Another module would display a
map based on the GPS location. How would the module Map get the location
from another module?
The module could "ask" the ModuleLoader to point to the module, which
provides the service "GPS" but
I still don't have an idea as how to get the information from the module. I could require that
if the module provides GPS service that he must have public properties:
X,Y,Z...

Another problem is module execution. Do I give each module it's own
execution thread?
Or perhaps just the ones that provide services?

Any ideas would REALLY help...
saso

Nov 15 '05 #2
That's the approach I was thinking about...
Just a few more questions...
Do your plugins inherit from IPlugin or do the implement it? I mean do you
have this:
class MyPlugin : System.Object, IPlugin ? (or MyPlugin:
System.Windows.Forms, IPlugin or ...)

In this case, isn't the Type of MyPlugin actually MyPlugin? To get the
interface
you would then have to use MyPlugin.GetType().GetInterface("IPlugin") and to
call
the methods of this interface you would then use MethodInfo.Invoke(...).
And most importantly... You can't cast an object of type MyPlugin to
IPlugin, can you?

Here's what I do so far:
I load all the types in an assembly. I go through all the types and search
if those types implement
IModule. I create an instance of the object which implements the IModule
interface with:
object myObject = Activator.CreateInstance(typeofObject);
I then use the MethodInfo.Invoke and PropertyInfo.GetValue, to start the
OnConnect method of
the plugin (OnConnect is part of IModule) and to get the list of Services
(also part of IPlugin) that the plugin provides (if any).
I then add "myObject", it's services and it's type into an array at the
host. So when some plugin would call:
Host.FindPlugin("GPS");
The Host would find that the GpsPlugin provides the GPS service and it would
provide the
object reference and Type to the plugin which requires the question.
The main problem is:
How do I cast the GpsPlugin (which is stored at the host and received as
System.Object) to the type
of GpsPlugin (note that the host stored the Type information)?

I wouldn't want to hardcode the casting... Is this even possible?

Thanks,
saso

"Sami Vaaraniemi" <sa***************@jippii.fi> wrote in message
news:bv**********@phys-news1.kolumbus.fi...
Here's what I do in a situation that is very similar to yours. My plugins
(or modules as you call them) implement interface IPlugin, and the shell
application that loads the plugins implements interface IHost. When the host loads a plugin it gives a reference to IHost to the plugin.

One of the methods in IHost is declared like so:

IPLugin GetPlugin(Type t);

In the implementation of this method, the host goes over all loaded plugins and returns a reference to the first plugin that implements type 't'.

Applying this approach to your case, in order to obtain a reference to the
GPS plugin and to get the location, your Map plugin would something similar to this:

IPlugin plugin = ihost.GetPlugin(typeof(IGpsPlugin));
IGpsPlugin gpsPlugin = (IGpsPlugin)plugin;
Location loc = gpsPlugin.Location;

This approach works for me just fine. Depending on your particular needs you might want to tweak the logic, but anyway this is the big picture.

Regards,
Sami

"Saso Zagoranski" <sa*************@guest.arnes.si> wrote in message
news:bv**********@planja.arnes.si...
Hi!

I mentioned this in my other post today but at that time I though I had it all figured out. When
I got a reply regarding my other questing I saw that I don't :)

Here's my problem:

I would like to have an application where I would write the core and the
users could write
their own addins for the application.
Even the basic features I would provide would be addins.

Here's my idea: Create a basic form, which would contain the ModuleLoader class. That class
would read the modules.xml file and dynamiclly load all the modules.
All the modules would have to implement the interface IModule, plus
IModuleMenu if the module
would add something to the menubar.
Here comes the tricky part...
Some of the modules could provide some services. Let's say I have a module,
which communicates with
a GPS device and provides the service GPS. Another module would display a map based on the GPS location. How would the module Map get the location
from another module?
The module could "ask" the ModuleLoader to point to the module, which
provides the service "GPS" but
I still don't have an idea as how to get the information from the

module. I
could require that
if the module provides GPS service that he must have public properties:
X,Y,Z...

Another problem is module execution. Do I give each module it's own
execution thread?
Or perhaps just the ones that provide services?

Any ideas would REALLY help...
saso


Nov 15 '05 #3

"Saso Zagoranski" <sa*************@guest.arnes.si> wrote in message
news:c0**********@planja.arnes.si...
That's the approach I was thinking about...
Just a few more questions...
Do your plugins inherit from IPlugin or do the implement it? I mean do you
have this:
class MyPlugin : System.Object, IPlugin ? (or MyPlugin:
System.Windows.Forms, IPlugin or ...)
My plugins inherit from IPlugin - which is the same as saying they implement
IPlugin. They also happen to be Forms, so they look like this (the second
option above):

class MyPlugin : System.Windows.Forms, IPlugin

Sometimes the plugins implement a plugin-specific interface, e.g.,

interface ISpecialPlugin : IPlugin {...}

class MySpecialPlugin : System.Windows.Forms, ISpecialPlugin

All these interfaces (IPlugin, ISpecialPlugin, IHost) are defined in an
assembly which is referenced by the plugins and by the shell.

In this case, isn't the Type of MyPlugin actually MyPlugin? To get the
interface
you would then have to use MyPlugin.GetType().GetInterface("IPlugin") and to call
the methods of this interface you would then use MethodInfo.Invoke(...).
And most importantly... You can't cast an object of type MyPlugin to
IPlugin, can you?
Yes, the actual type of MyPlugin is MyPlugin. Due to the fact that MyPlugin
and all other plugins inherit from IPlugin, the shell can easily access the
IPlugin interface when it loads the plugin:

Assembly asm = Assembly.LoadFrom(<url>); // this string comes from
e.g., a config file
IPlugin plugin = (IPlugin)asm.CreateInstance("MyPlugin"); // the string
"MyPlugin" string comes from e.g., a config file

This way the shell can call the methods of IPlugin directly and there is no
need to invoke them through reflection. The shell only uses the interface,
it never uses the actual type MyPlugin.

Here's what I do so far:
I load all the types in an assembly. I go through all the types and search
if those types implement
IModule. I create an instance of the object which implements the IModule
interface with:
object myObject = Activator.CreateInstance(typeofObject);
I then use the MethodInfo.Invoke and PropertyInfo.GetValue, to start the
OnConnect method of
the plugin (OnConnect is part of IModule) and to get the list of Services
(also part of IPlugin) that the plugin provides (if any).
This sounds fine to me except that you don't necessarily have to use
MethodInfo.Invoke. Instead, simply cast your object to IModule:

object myObject = Activator.CreateInstance(typeofObject);
IModule module = (IModule)myObject;

In order for this to work though, you need to define the interface IModule
in a separate assembly and have your loader application reference that
assembly.
I then add "myObject", it's services and it's type into an array at the
host. So when some plugin would call:
Host.FindPlugin("GPS");
The Host would find that the GpsPlugin provides the GPS service and it would provide the
object reference and Type to the plugin which requires the question.
The main problem is:
How do I cast the GpsPlugin (which is stored at the host and received as
System.Object) to the type
of GpsPlugin (note that the host stored the Type information)?
My earlier comments already answer this. Define the interface IGpsPlugin in
a shared assembly. Have the plugin reference that assembly. Then in the
plugin you can simply write:

IGpsPlugin gpsPlugin = (IGpsPlugin)Host.FindPlugin(typeof(IGpsPlugin));

You will not need to use reflection if you define the interfaces in a
separate assembly, and have the host and the plugins reference this
assembly. I know that some developers prefer the flexibility of reflection
over having interfaces. My personal preference (in this case) is type safety
through interfaces.
I wouldn't want to hardcode the casting... Is this even possible?

Thanks,
saso


Sure,
Sami

Nov 15 '05 #4
Thanks Sami!
You really helped me a lot!

Just one more thing :)
How do you "cast" an object if you have the Type of the object stored in
some variable t?
So you can't use:
myGpsObject = (Gps) myObject;

but instead:
myGpsObject = ??? t.GetType() ???

Again,
thanks a lot for your help

"Sami Vaaraniemi" <sa***************@jippii.fi> wrote in message
news:c0**********@phys-news1.kolumbus.fi...

"Saso Zagoranski" <sa*************@guest.arnes.si> wrote in message
news:c0**********@planja.arnes.si...
That's the approach I was thinking about...
Just a few more questions...
Do your plugins inherit from IPlugin or do the implement it? I mean do you have this:
class MyPlugin : System.Object, IPlugin ? (or MyPlugin:
System.Windows.Forms, IPlugin or ...)
My plugins inherit from IPlugin - which is the same as saying they

implement IPlugin. They also happen to be Forms, so they look like this (the second
option above):

class MyPlugin : System.Windows.Forms, IPlugin

Sometimes the plugins implement a plugin-specific interface, e.g.,

interface ISpecialPlugin : IPlugin {...}

class MySpecialPlugin : System.Windows.Forms, ISpecialPlugin

All these interfaces (IPlugin, ISpecialPlugin, IHost) are defined in an
assembly which is referenced by the plugins and by the shell.

In this case, isn't the Type of MyPlugin actually MyPlugin? To get the
interface
you would then have to use MyPlugin.GetType().GetInterface("IPlugin") and
to
call
the methods of this interface you would then use MethodInfo.Invoke(...).
And most importantly... You can't cast an object of type MyPlugin to
IPlugin, can you?
Yes, the actual type of MyPlugin is MyPlugin. Due to the fact that

MyPlugin and all other plugins inherit from IPlugin, the shell can easily access the IPlugin interface when it loads the plugin:

Assembly asm = Assembly.LoadFrom(<url>); // this string comes from e.g., a config file
IPlugin plugin = (IPlugin)asm.CreateInstance("MyPlugin"); // the string "MyPlugin" string comes from e.g., a config file

This way the shell can call the methods of IPlugin directly and there is no need to invoke them through reflection. The shell only uses the interface,
it never uses the actual type MyPlugin.

Here's what I do so far:
I load all the types in an assembly. I go through all the types and
search if those types implement
IModule. I create an instance of the object which implements the IModule
interface with:
object myObject = Activator.CreateInstance(typeofObject);
I then use the MethodInfo.Invoke and PropertyInfo.GetValue, to start the
OnConnect method of
the plugin (OnConnect is part of IModule) and to get the list of Services (also part of IPlugin) that the plugin provides (if any).


This sounds fine to me except that you don't necessarily have to use
MethodInfo.Invoke. Instead, simply cast your object to IModule:

object myObject = Activator.CreateInstance(typeofObject);
IModule module = (IModule)myObject;

In order for this to work though, you need to define the interface IModule
in a separate assembly and have your loader application reference that
assembly.
I then add "myObject", it's services and it's type into an array at the
host. So when some plugin would call:
Host.FindPlugin("GPS");
The Host would find that the GpsPlugin provides the GPS service and it

would
provide the
object reference and Type to the plugin which requires the question.
The main problem is:
How do I cast the GpsPlugin (which is stored at the host and received as
System.Object) to the type
of GpsPlugin (note that the host stored the Type information)?


My earlier comments already answer this. Define the interface IGpsPlugin

in a shared assembly. Have the plugin reference that assembly. Then in the
plugin you can simply write:

IGpsPlugin gpsPlugin = (IGpsPlugin)Host.FindPlugin(typeof(IGpsPlugin));
You will not need to use reflection if you define the interfaces in a
separate assembly, and have the host and the plugins reference this
assembly. I know that some developers prefer the flexibility of reflection
over having interfaces. My personal preference (in this case) is type safety through interfaces.
I wouldn't want to hardcode the casting... Is this even possible?

Thanks,
saso


Sure,
Sami

Nov 15 '05 #5

"Saso Zagoranski" <sa*************@guest.arnes.si> wrote in message
news:c0**********@planja.arnes.si...
Thanks Sami!
You really helped me a lot!

Just one more thing :)
How do you "cast" an object if you have the Type of the object stored in
some variable t?
So you can't use:
myGpsObject = (Gps) myObject;

but instead:
myGpsObject = ??? t.GetType() ???


You cannot get an instance out of a type simply by casting. When you cast,
you always cast a reference to an instance, like so:

object obj = new SomeClass();
// Now cast 'obj' to a reference to 'SomeClass'
SomeClass sc = (SomeClass)obj;

Btw, there are a number of articles on the net that show how to create a
pluggable architecture. I know there is one on www.codeproject.com (I can't
seem to access it now). There's another one written in VB.NET on
developerfusion.com: http://www.developerfusion.com/show/4371/ .

I also wrote a quick C# sample that shows one way of doing a pluggable
architecture. It is very similar to the articles above. My sample is
available for download at http://www.capehill.net/pluginsample.zip . I might
add some security specific stuff to this sample later if I have the time...

Sami

Nov 15 '05 #6
I did something very similar to what you have...
I just have a config file to load the modules...

What do you mean by security? Controling access to the modules? Where can I
find some
reading on this subject?

Again, thanks for all your help
saso

"Sami Vaaraniemi" <sa***************@jippii.fi> wrote in message
news:c0**********@phys-news1.kolumbus.fi...

"Saso Zagoranski" <sa*************@guest.arnes.si> wrote in message
news:c0**********@planja.arnes.si...
Thanks Sami!
You really helped me a lot!

Just one more thing :)
How do you "cast" an object if you have the Type of the object stored in
some variable t?
So you can't use:
myGpsObject = (Gps) myObject;

but instead:
myGpsObject = ??? t.GetType() ???
You cannot get an instance out of a type simply by casting. When you cast,
you always cast a reference to an instance, like so:

object obj = new SomeClass();
// Now cast 'obj' to a reference to 'SomeClass'
SomeClass sc = (SomeClass)obj;

Btw, there are a number of articles on the net that show how to create a
pluggable architecture. I know there is one on www.codeproject.com (I

can't seem to access it now). There's another one written in VB.NET on
developerfusion.com: http://www.developerfusion.com/show/4371/ .

I also wrote a quick C# sample that shows one way of doing a pluggable
architecture. It is very similar to the articles above. My sample is
available for download at http://www.capehill.net/pluginsample.zip . I might add some security specific stuff to this sample later if I have the time...
Sami

Nov 15 '05 #7

"Saso Zagoranski" <sa*************@guest.arnes.si> wrote in message
news:c0**********@planja.arnes.si...
I did something very similar to what you have...
I just have a config file to load the modules...

What do you mean by security? Controling access to the modules? Where can I find some
reading on this subject?


If your application allows for extensibility via remotely loaded plugins,
you will probably want to make sure that you load only plugins that you know
you can trust. In practice this would boil down to checking that the plugin
assemblies are properly signed.

There are some articles e.g., on MSDN that touch this topic briefly, e.g.,
http://msdn.microsoft.com/netframewo...artclient.aspx .

Sami
Nov 15 '05 #8

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

Similar topics

14
by: Hayden Kirk | last post by:
Hey guys I am about to write some back end software for my business. I want a system that I can create invoices, clients etc... I can do this no problem. However I want to write it in modules so...
5
by: Tim | last post by:
Dear All, I have been working with VB.NET for the last 5 months or so as a solo developer for a small business. I have already started developing the application but have hit a snag with the...
1
by: Derek | last post by:
Hi All, I am developing a Windows based application that consists of several different modules. These modules are effectively separate from each other yet share information in a common database....
4
by: Nick Goloborodko | last post by:
Hi, I'm in the process of conceptualizing a new ASP.NET application. I'm a relative newbie in ASP.NET / .NET in general, so any comments will be greatly appreciated. Basically i need to make...
12
by: Don Huan | last post by:
Hi my job is to migrate our WinForms application to ASP.NET. This app was build very modular so every peace of code can be replaced by another "modul". There are 1 VS-solution with about 60...
26
by: I_AM_DON_AND_YOU? | last post by:
This is the scenario: I have a VB.Net project comprising of a few Forms. On Form1 I have more than 20 buttons. There is a very lenghty code written in click event of each and every button. Right...
2
by: Peter Kubicsek | last post by:
Hi I need help. I'm trying to write modular APP which have only basic interfaces to work with database, and etc. All specific code will be in modules (dll's), which can be loaded/unloaded from...
0
by: Leif K-Brooks | last post by:
I'm writing an application with PostgreSQL as the database which I would like to be as modular as possible. It will have various modules, each of which will have their own database schema. A module...
20
by: Tuvas | last post by:
I have made and recently posted a libary I made to do Modular Arithmetic and Prime numbers on my website at http://www.geocities.com/brp13/Python/index.html . I am currently in a crypotology...
2
by: Canice | last post by:
I'm working on a web application where 90% of it is common 'product' code an the other 10% is customer specific. I want some method of separating the customer specific presentation, business and...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.