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 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
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
"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
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
"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
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
"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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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....
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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...
|
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...
|
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,...
|
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...
|
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,...
|
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...
|
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...
|
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,...
| |