"Optional" reference?

S

Steve

Kind of a strange question... I have a VB.NET 2.0 solution containing
a main project (my EXE) and a number of other projects (class DLLs)
that are "plug-ins" to the main app. These plugins get installed
depending on each user's requirements.

I'd like to implement a function in one plugin that only executes if
another plugin is present. Typically, for one plugin to access a
second plugin, I need to set a reference at design-time to the second
project within the first project. However, to create this new
function, I can't be sure the second plugin will exist. I want to
determine the existence of the second plugin (DLL) at run-time, and if
present, create a reference to it that will allow the first plugin to
access functionality within the second.

Does any of this make sense or am I rambling too much? I can provide
more details if necessary. TIA... Steve
 
G

GhostInAK

Hello Steve,

Just ask the host if the required plugin is installed.. if it is you can
then ask the host for a reference to it.

-Boo
 
C

Chris Dunaway

Steve said:
Kind of a strange question... I have a VB.NET 2.0 solution containing
a main project (my EXE) and a number of other projects (class DLLs)
that are "plug-ins" to the main app. These plugins get installed
depending on each user's requirements.

I'd like to implement a function in one plugin that only executes if
another plugin is present. Typically, for one plugin to access a
second plugin, I need to set a reference at design-time to the second
project within the first project. However, to create this new
function, I can't be sure the second plugin will exist. I want to
determine the existence of the second plugin (DLL) at run-time, and if
present, create a reference to it that will allow the first plugin to
access functionality within the second.

For a plug in type app, each plug in should reference a plugin
*interface* and not the plugin it self. That way the plugin that
depends on another plugin need not reference the particular dll of the
other plugin. It just references the Interface. It would then, as
Ghost said, ask the host app (probably through another interface) if
the other plugin is installed. And if so, access it through the
interface. One other consideration is the order in which the plugins
are loaded. To me it would be safer to not start the plugins until
they are all loaded by the host. Or at least when the first plugin
requests the other plugin, if it is not loaded yet by the host, the
host can load it right then. (Did *that* make sense?)

Perhaps some pseudo code would help. The Host app implements the IHost
interface. Which has a GetPlugin method (it may have more methods).
It then looks in some folder on the hard drive or perhaps checks a
config file to find out where the plugin assemblies are located and
loads each one, adds it to the list of loaded plugins, and then calls
its execute method to start it. It passes in a reference to itself
(IHost) to each plugin.

Inside the plugin, if it needs services from the host, it can use the
IHost interface to call methods or make requests of the host. The code
below is pretty crude. You would need to make sure that it is safe for
each plugin to call the host at the same time or otherwise coordinate
access by each plugin.

HostInterface:

Public Interface IHost
Public Function GetPlugin(pluginName As String) As IPlugin
End Interface

PlugInInterface:

Public Interface IPlugin
Dim PluginName As String
Public Sub Execute(host As IHost)
'Add other methods here
End Interface

HostInterface and PluginInterface could reside in the same assembly.

Plugins:

'PluginOne.dll
'PluginOne only needs to reference the interface IPlugin assembly
Public Class PluginOne : Implements IPlugin

Dim PluginName As String
Private _host As IHost

Public Sub New()
PluginName = "Plugin1"
End Sub

Public Sub Execute(host As IHost) Implements IPlugin.Execute
_host = host
End Sub
End Class

'PluginTwo.dll
'Plugin 2 needs to see if Plugin1 is loaded but it still only needs
'to referecne IPlugin assembly and not the actual plugin dll
Public Class PluginTwo : Implements IPlugin

Dim PluginName As String
Private _host As IHost

Public Sub New()
PluginName = "Plugin2"
End Sub

Public Sub Execute(host As IHost) Implements IPlugin.Execute

_host = host

'Find out if the other plugin is loaded. This should probably
be a parameter in
'a config file in case the name of Plugin1 ever changes.
IPlugin plugin1 = _host.GetPlugin("Plugin1")

If plugin1 IsNot Nothing Then
'Do something with the other plugin here
End If
End Sub
End Class


'Host App

Public Class Host : Implements IHost

Public Shared Sub Main(args() As String)
Dim _instance As New Host()
_instance.Execute()
End Sub

'Check my generics syntax
Private _plugins As Dictionary(Of String, Of IPlugin)

Public Sub New()
_plugins = New Dictionary(Of String, Of IPlugin)()
End Sub

Public Sub Execute()
'Run the host here
LoadPlugins() 'Loads the plugins into its dictionary
End Sub

Public Function GetPlugin(name As String) As IPlugin
If _plugins.ContainsKey(name) Then
Return _plugins(name)
Else
'plugin not found in our list
'Try to load it here and if successful, return it else
return Nothing
End If
End Function

Private Sub LoadPlugins()
'populate the _plugins dictionary
For Each Dll In Some Folder
IPlugin p = Activator.CreateInstance() 'Creates an
instance of the plugin
_plugins.Add(p.PluginName, p) 'Add the plugin to our
list
p.Execute(Me) 'Execute the plugin, pass in the IHost
Next
End Sub

End Class


Whew! That was pretty long winded, but hopefully you will glean
something good from it! This is not necessarily the *only* way to
implement a plugin type architecture, but it should give you some
ideas.

Good Luck

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top