Plugin based development

Plugin based development


I’m currently working on a software project for a well known Church based over in Los Angeles where we are installing an online ordering portal, the site in question uses ASP NET Webforms, but is an LOB (Line of Business) application used by many over vendors in our market. We need to integrate with the customer at the payment stage in order to:

  1. Update their internal system with the information from our system.
  2. Collect payment for the order.

Code

As we need this system to be totally independent of our core system, we need to be able to reference these “Plugins” from an outside source, but we need to know what these interfaces actually do!

The answer is simple. Interfaces.

An interface is a method of declaring what properties, methods a particular CLR type is compatible with. Most of us use this without knowing about it every day, when you use:

For Each item in collection
    item.PerformAction()
Next item

You are actually referencing the IEnumerable(Of T) interface, which tells the compiler I am able to Enumerate and yield a value several times from this object.

So, we’ve decided that we need an Interface, but how do we actually load these dll’s at run time? It can be a big question at first, (it was for me) – but after consulting with Dr. Google I found the classes I needed.

First, System.Assembly. It provides us with all the gubbins we need to load and inspect an assembly dynamically at run time.

assemblyToLoad = System.Reflection.Assembly.LoadFile(file)

This function will physically load the CLR with this assembly, in order for us to inspect it using the System.Type class.

Dim interfaces() As System.Type
interfaces = assemblyToLoad.GetExportedTypes()

So a couple things to note on the above example, first, we are using “GetExportedTypes.” The reason you want this method is because it only returns the types that are availiable to anything external. If you use the other methods, you may find more interface implementations than you were supposed to, or, you’ll find internal .NET generated classes like MySettings classes. Public declarations were invented for a reason – Make sure you use them correctly!

So, if we put what we know together we could make this a nice generic function, and for extra type safety we include a base “IPlugin” interface, it allows us both sides to ensure the class/interface we are loaded was meant to be a plugin. Here’s the code in full:

Public Class Plugins

    Public Interface IPlugin
        Property AssemblyPath As String
    End Interface

    Public Shared Function EnumerateFolder(Of T As IPlugin)(ByVal directory As String) As List(Of T)
        Dim assembly As Reflection.Assembly
        Dim foundPlugins As New List(Of T)
        Dim types() As Type
        Dim filter As Reflection.TypeFilter
        Dim plugin As T

        filter = New Reflection.TypeFilter(Function(m As Type, criteria As Object)
                                               Return True
                                           End Function)

        For Each file In IO.Directory.EnumerateFiles(directory, "*.dll", IO.SearchOption.TopDirectoryOnly)
            Try
                assembly = System.Reflection.Assembly.LoadFile(file)

                For Each foundType As System.Type In assembly.GetExportedTypes
                    types = foundType.FindInterfaces(filter, Nothing)

                    If types.Contains(GetType(T)) And types.Contains(GetType(IPlugin)) Then
                        plugin = Activator.CreateInstance(foundType)
                        plugin.AssemblyPath = file
                        foundPlugins.Add(plugin)
                    End If

                Next
            Catch ex As Exception
                'not a .net assembly
            End Try
        Next

        Return foundPlugins
    End Function

End Class
Enjoy.
About these ads

One thought on “Plugin based development

  1. Pingback: Getting started with Multifile assembly – Part II

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s