|
-
Dec 7th, 2012, 04:33 PM
#1
Thread Starter
PowerPoster
Plug-in Based Application (Step by Step)
Hi,
I've been searching the web on how to create an application which uses plugins. Now there are a lot of websites, but it seems they all use the same method, which I don't understand. (Seems they all copy from the same source)
What I want to do is -> open application/form -> load plug-in(s) -> create CommandButtons (whatever) of the plug-in(s) on main form -> click on button -> plug-in-interface creates a new TabPage (whatever) ... adds a textbox, adds a... blabla, etc. (you catch my drift)
What I do understand is that I need to create a ClassLibrary (as project) when I want it to be a plugin.
Let's start with the basic steps I took
Step 1 - I created a project named "Example"
Step 2 - I added a class (myPlugin) to the project "Example"
Step 3 - I changed the code of myPlugin to:
Code:
Public Interface myPlugin
ReadOnly Property title() As String
End Interface
What does that mean? What does it do? Are there more things I need to add? Once I know the answer to these kind of questions I have, I perhaps can go on to the next step.
Thanks in advance.
I'm using VS2012 Professional btw.
-
Dec 7th, 2012, 05:47 PM
#2
Re: Plug-in Based Application (Step by Step)
they all use the same method
Well that's not exactly surprising, is it? Why would there be a stack of near duplicate methods to achieve the same basic functionality. This Dream-In-Code article seems pretty straightforward to me. I'm really not sure that there's much we can tell you that isn't already there.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Dec 8th, 2012, 03:17 AM
#3
Thread Starter
PowerPoster
Re: Plug-in Based Application (Step by Step)
Not really answering my question. But that is the code I'm trying to understand.
-
Dec 8th, 2012, 07:09 AM
#4
Re: Plug-in Based Application (Step by Step)
Radjesh, creating an application that supports plugins does take a little more understanding of application architecture than an ordinary programmer has. It would be good if you can summarize your programming experience so far so that members here can provide you better help. Also you can go through the Visual Studio Add In creation process to understand a bit better how plugins work in Visual Studio.
.
-
Dec 9th, 2012, 04:10 AM
#5
Thread Starter
PowerPoster
Re: Plug-in Based Application (Step by Step)
Hi Honeybee, thanks for the reply. Wel... A lot of people here know what I'm capable of, since I'm around since 2005. Last few months not much due to my new job.
Once I understand the code, what it actually does, I can manage to do stuff on my own. Need no help to create the application itself, but I need to understand which steps I need to take to make it "pluginnable". I need to understand the code obviously, so I can mange on my own.
-
Dec 9th, 2012, 09:32 PM
#6
Re: Plug-in Based Application (Step by Step)
In that case you would do well to try out the Visual Studio Add Ins, how they are pluggable. The other ready source of understanding how it works is the MS Office automation, where you can use objects of the MS Office application to create Office documents. That should give you ample insight into how things have to be architectured.
.
-
Dec 9th, 2012, 10:04 PM
#7
Re: Plug-in Based Application (Step by Step)
I have been working on a plug-in system for some time now, and might be of some use...except that I am about to leave for a conference, so you won't be hearing from me for a week.
Anyways, the way I went about it was to come up with an interface of the methods with which the the main program would interact with the modules. It looks like this:
Code:
Public Interface IHISGeneral
#Region "Properties"
ReadOnly Property DisplayFactors() As HISInterfaceItems
Property ConnectionString() As String
ReadOnly Property IsInitialized() As Boolean
ReadOnly Property ModuleName() As String
ReadOnly Property ModuleDescription() As String
ReadOnly Property ModuleToolTip(Optional ByVal RUID As Guid = Nothing) As String
ReadOnly Property EventString() As String
ReadOnly Property RUID As Guid
Property AUID As List(Of Guid)
#End Region
#Region "Methods"
Function Initialize(ByVal connectionString As String, ByVal eRaiser As EventRaiser) As Boolean
Sub OnMenuSelect(ByVal RUID As Guid)
Sub OnConfigMenuSelect()
Function OnDrop(ByRef FishArgs As FishEventArgs) As Boolean
Function GetErrors() As String
Sub EditRequest(ByVal EventInfo As EventWrapper)
#End Region
End Interface
What I was looking for was the core common functionality. Many of the items in that interface are kind of boilerplate things. Basically, any method that returns a string is a way for the module to supply some descriptive information that the user might get to see. You can largely gloss over those methods.
One interesting item is the DisplayFactors. I needed to have a variety of things that would be necessary for displaying the item. Some of these could have been part of the interface, such as where the thing should be displayed (since that would just return an Enum value). However, I decided to package all these various things up into a single class and have the interface return an instance of that class. To a large extent, I did this because I didn't want to add too many items to the interface. In practice, it probably mattered very little.
One critical point is that any class that implements the interface can't have much of a constructor of its own. After all, I have to create instances of the class in a very generic fashion, so if they had constructors, they would all have to take EXACTLY the same arguments, which seemed a bit restrictive, and may not even have worked. Therefore, there is the Initialize method that supplies a couple things. The Initialize method has to be called to set up the object underlying the interface, whatever the object actually is.
A further point is the OnDrop and MenuSelect methods. You can guess what those two do from their names. I needed a generic way to hook the objects up to the main form interface, and the modules would interact with other modules by being dragged and dropped, or by being selected from a menu (and often both are available), so those two methods are there to supply a common means to get that functionality.
The rest of the methods are things that are specific to my particular design and would have no general interest. You will probably have such things that will be specific to your design. I would suggest starting with the least you think you can get away with and adding items as you find them essential.
The interface, along with both the EventRaiser class and the HISInterfaceItems class, is defined in a dll. ALL modules that will be plugins need to reference this dll so that they have knowledge of the interface.
When the main program starts up, it looks through all the dlls in a specific folder looking for objects that implement the interface. The code for that looks like this:
Code:
If IO.Directory.Exists("C:\IFWIS\HIS\") Then 'Search a specific folder.
For Each fl As String In IO.Directory.GetFiles("C:\IFWIS\HIS\", "*.dll") 'For all files of type dll.
Try
Dim aDLL As System.Reflection.Assembly = System.Reflection.Assembly.LoadFile(fl)
If aDLL IsNot Nothing Then
Dim tArr As Type() = aDLL.GetExportedTypes 'Get all the types in the dll.
For Each t As Type In tArr
If t.GetInterface("HISInCommon.IHISGeneral") IsNot Nothing Then 'Look for types that implement the interface.
Dim o As HISInCommon.IHISGeneral = DirectCast(aDLL.CreateInstance(t.FullName), HISInCommon.IHISGeneral) 'Create one instance of the object.
If o IsNot Nothing Then
o.Initialize(globalConString, eRaiser) 'Initialize the instance (much like a constructor)
If o.IsInitialized Then
'If initialization worked, the object is the right type, and is ready for use.
One last thing I will mention is the EventRaiser class. The point is to have one shared class that can raise events. The main program creates an instance of the EventRaiser, then passes it along to all the other objects (not just plug-ins, actually). By doing this, all the modules can communicate between each other. Since they all hold a reference to that one common object, they can all receive events raised by that common object. Initially, I thought there would be only three or four events in the EventRaiser, along with public methods that a class can call to have the ER raise the event. As it turned out, this was a really nice idea, and the event list is now sitting around two dozen different events along with a few other member variables that the modules can interact with.
Hope that helps a bit. If not....well, I won't know for a week.
My usual boring signature: Nothing
 
-
Dec 10th, 2012, 05:58 AM
#8
Re: Plug-in Based Application (Step by Step)
Hi Radjesh,
The dotnet framework has built-in plugin support. The Managed Extensibility Framework (MEF) page on msdn provides a walk-through in VB.Net. Maybe it will help you to get a clearer picture in combination with the other advice you have received. I have studied the example a little but not yet tried applying it in practice.
BB
-
Dec 15th, 2012, 03:18 AM
#9
Thread Starter
PowerPoster
Re: Plug-in Based Application (Step by Step)
Will have a look at your solution guys. Thanks so far. Will let you know.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|