Question My plan for dynamic add-on loading - Thoughts?

Naigewron

Member
Joined
Jul 23, 2007
Messages
5
Location
Bergen, Norway
Programming Experience
5-10
Hi!

I am currently developing an application that will be the "base" for several components (business reporting systems, order management, etc). The idea is that our customers will install this "mother application", and we will offer components that will slot into it, expanding the functionality.

Now, here's my idea for how to make this work. I have some of this basic functionality down, but I want to get other people's opinions, ideas and experiences with this sort of thing before I move too far in a direction that might not be the best way to go:

- The components have an "interface" that is inherited from a base class that both the mother application and the component knows about. This will be their means of communicating with eachother

- The components are compiled into DLLs. The mother application goes through these DLLs and looks for an implementation of the base interface:

Here is the "complete" Sub for loading the components
VB.NET:
  Public LoadedModules As New ModuleCollection 

  Private Sub LoadModules()
    Try
      ' Information installed modules is stored in a database table.
      ' Retrieve it and go through the data rows to load each module
      Dim dtModules As New SystemDataset.BUS_InstalledModulesDataTable
      g_taInstalledModules.Fill(dtModules)

      ' Clear the module collection
      LoadedModules.Clear()

      For Each rw As SystemDataset.BUS_InstalledModulesRow In dtModules.Rows

        ' The module directory name.
        ' MODULES_FOLDER is just a string constant containing the
        ' application path subfolder name where the modules reside
        Dim dirInfo As New System.IO.DirectoryInfo(Application.StartupPath & "\" & MODULES_FOLDER & "\" & rw.ModuleFolder)

        Try
          ' Just check some folder rights and stuff
          If CheckFolderRights(dirInfo.FullName) <> FolderRight.Full Then
            Throw New Exception("Insufficient access to module folder '" & _
            rw.ModuleFolder & "' (need full read/write access)! " & _
            "Aborting module load for module '" & rw.Name & "'.")
          End If

          ' Create an assembly object and try to load the
          ' assembly name from the datarow (e.g. "ComponentName")
          Dim asm As Reflection.Assembly
          asm = Reflection.Assembly.LoadFrom(dirInfo.FullName & "\" & rw.ModuleAssembly)

          ' Try to create an instance of the common interface,
          ' so that the mother application will have an object to
          ' communicate with the component through
          Dim mdl As BaseModule
          mdl = asm.CreateInstance(rw.ModuleNamespace & "." & rw.ModuleInterface)
          mdl.ModuleId = rw.Module_ID

          ' Add the newly loaded component to the collection
          LoadedModules.Add(mdl)

        Catch ex As Exception
          ExceptionHandler(ex)
        End Try
      Next

    Catch ex As Exception
      ExceptionHandler(ex)
    End Try
  End Sub

The important bit is really this, which deals with the creating and loading of a named assembly:
VB.NET:
          ' Create an assembly object and try to load the
          ' assembly name from the datarow (e.g. "ComponentName")
          Dim asm As Reflection.Assembly
          asm = Reflection.Assembly.LoadFrom(dirInfo.FullName & "\" & rw.ModuleAssembly)

          ' Try to create an instance of the common interface,
          ' so that the mother application will have an object to
          ' communicate with the component through
          Dim mdl As BaseModule
          mdl = asm.CreateInstance(rw.ModuleNamespace & "." & rw.ModuleInterface)
          mdl.ModuleId = rw.Module_ID

ModuleCollection is simply a class that extends CollectionBase:
VB.NET:
Public Class ModuleCollection
  Inherits System.Collections.CollectionBase

  Public Sub Add(ByVal Mdl As BaseModule)
    ' Invokes Add method of the List object to add a widget.
    List.Add(Mdl)
  End Sub

  Public Sub Remove(ByVal index As Integer)
    If index > Count - 1 Or index < 0 Then
      Throw New Exception("Error removing item! No module at index " & index & "!")
    Else
      List.RemoveAt(index)
    End If
  End Sub

  Public ReadOnly Property Item(ByVal index As Integer) As BaseModule
    Get
      Return CType(List.Item(index), BaseModule)
    End Get
  End Property
End Class

(I'm aware that referring to the components as "Modules" might make the code a bit hard to read, and I've since realised the error of my ways. This will be rewritten ;) )


Hopefully this post makes some sense. Basically, The mother application needs to dynamically load "add-on" components that are not compiled into or together with the actual application (ie: The mother application has absolutely zero knowledge about the component at compile-time). We need to be able to add a DLL to the application at any time, and have the mother application be able to use it to load MDI child forms, menus, toolstrips and generally use it to expand its own functionality. Am I on the right path here, or is there some other way I should look at?
 
Last edited:
Back
Top