Create a Plug-In Based ApplicationCreating a Plug-In based application follows 3 basic steps
1. Defining an Interface
This where we define the contract for the plug-in.
2. Creating a Plug-In
How to create the Plug-In
3. Loading a Plug-In
How to load the Plug-In into your application.
I going to base this tutorial around a console application, to focus on the core coding needed. It can be extrapolated to a windows form application.
So lets begin.
Create a new Console application called
Tutorial_PlugIns.
In the solution explorer add a new class. Called
IPlugIn1. Defining An InterfaceAn Interface is the contract that the plugins must follow to be a plugin.
For this tutorial we'll keep it simple, but in your application it can be as complex as it needs to be.
Change the code of IPlugIn class to this.
CODE
Public Interface IPlugIn
ReadOnly Property Title() As String
Sub DoThis()
Function DoSomething(A As Double,B As Double) As Double
End Interface
Now save the application, noting where the application is save (as we'll need it later on)
2. Creating a PluginTo Create our first Plug-In we need to add another project to our solution.
File -> Add -> Add Project -> Class Library
Name it
FirstPlugInNext we need to add a reference to our previously created project, so we can access the IPlugIn Interface.
Add a reference to the Main Project
Underneath the class name add
s Tutorial_Plugins.IPlugin, note how it adds all the required information for the plugin.
CODE
Public Class MyFirstPlugIn
Implements Tutorial_Plugins.IPlugin
Public Function DoSomething(ByRef A As Double, ByVal B As Double) As Double Implements Tutorial_Plugins.IPlugin.DoSomething
End Function
Public Sub DoThis() Implements Tutorial_Plugins.IPlugin.DoThis
End Sub
Public ReadOnly Property Title() As String Implements Tutorial_Plugins.IPlugin.Title
Get
End Get
End Property
End Class
Now we need to give the Plug-In some functionality.
CODE
Public Class MyFirstPlugIn
Implements Tutorial_Plugins.IPlugin
Public Function DoSomething(ByRef A As Double, ByVal B As Double) As Double Implements Tutorial_Plugins.IPlugin.DoSomething
Return A + B
End Function
Public Sub DoThis() Implements Tutorial_Plugins.IPlugin.DoThis
Beep
End Sub
Public ReadOnly Property Title() As String Implements Tutorial_Plugins.IPlugin.Title
Get
Return "Beep & Add Together"
End Get
End Property
End Class
Save the solution.
No go to Build -> Build FirstPlugIn
At this stage we have built the Plug-In, now we must create the code that utilities it.
3. Loading a Plug-InAdd a new Module to the Main Project called Plugins add the following code.
To make the loading plugin simpler I devise a subroutine to help us.
CODE
Imports System.Reflection
Namespace Plugins
Public Module Plugins
#Const TRACE_Plugin = True
''' <summary>
''' A Generic Plugin Loader.
''' </summary>
''' <typeparam name="PlugType">The BaseClase of the Interface.</typeparam>
''' <param name="PluginList">A Collection into which to store the found plugins.</param>
''' <param name="LocationOfPlugins">The directory where the plugin DLLs are located.</param>
''' <param name="InterfaceName">The name of the inteface; </param>
''' <remarks></remarks>
Public Sub LoadPlugins(Of PlugType)(ByRef PluginList As ICollection(Of PlugType), ByRef LocationOfPlugins As String, ByVal InterfaceName As String)
#If TRACE_Plugin Then
Console.WriteLine("Searching For Plugins[{0}]", InterfaceName)
Console.WriteLine("In: {0}", LocationOfPlugins)
#End If
PluginList.Clear()
Dim Plugin_DLLs As System.Collections.ObjectModel.ReadOnlyCollection(Of String) = FileIO.FileSystem.GetFiles(LocationOfPlugins, FileIO.SearchOption.SearchTopLevelOnly, "*.dll")
Dim assemblyObj As Reflection.Assembly
Dim aDescAttr As AssemblyDescriptionAttribute
Dim aTitleAttr As AssemblyTitleAttribute
For Each PluginDLL As String In Plugin_DLLs
assemblyObj = Reflection.Assembly.LoadFrom(PluginDLL)
For Each t As Type In assemblyObj.GetTypes
If t.IsPublic Then
For Each ThisParticularType As Type In t.GetInterfaces
Try
If ThisParticularType.FullName = InterfaceName Then
PluginList.Add(CType(assemblyObj.CreateInstance(t.FullName, True), PlugType))
aDescAttr = CType(AssemblyDescriptionAttribute.GetCustomAttribute(assemblyObj, GetType(AssemblyDescriptionAttribute)), AssemblyDescriptionAttribute)
aTitleAttr = CType(AssemblyTitleAttribute.GetCustomAttribute(assemblyObj, GetType(AssemblyTitleAttribute)), AssemblyTitleAttribute)
#If TRACE_Plugin Then
Console.WriteLine("{0} {1}", PluginList.Count, aTitleAttr.Title)
#End If
End If
Catch e As Exception
' Console.WriteLine(String.Format("!! Exeception: {0}", e.Message))
' Throw e
End Try
Next
End If
' System.Threading.Thread.Sleep(500)
Next
Next
#If TRACE_Plugin Then
Console.WriteLine("Found {0} Plugins.", PluginList.Count)
#End If
End Sub
End Module
End Namespace
It use Generics, to make things simpler.
Plugins.LoadPlugins(Of {Name Of Interface})({Collection to contain the plugins}, {Where plugins are located}, {Full Name of Interface})Inside the Sub Main() add the following code. (Which loads the Plug-Ins, Display it's Title, Runs DoThis, Performs the Function DoSomeThing(4,5))
CODE
Module Module1
Sub Main()
Dim pl As New List(Of IPlugin)
Plugins.LoadPlugins(Of IPlugin)(pl, My.Application.Info.DirectoryPath & "\PlugIns\", "Tutorial_Plugins.IPlugin")
For Each p As IPlugin In pl
Console.WriteLine(p.Title)
p.DoTHis()
Console.WriteLine(p.DoSomething(4, 5))
Next
Console.ReadLine()
End Sub
End Module
If you run the application now, you see it can't find any plugins
Tutorial_Plugins -> FirstPlugIn -> Bin ->Debug
Copy
FirstPlugIn.dll to Tutorial_Plugins->Bin->Debug->PlugIns
Run Again.
Recap
1. Create an Interface
2. Create the Plug-In
3. Load & Use the Plug-In
This tutorial has only touched the basics of Plug-In but it has give you enough information so you can create you own more complex ones.
So now you'll be a Plug-In wielding coding ninja
