Imports System.IO Imports System.Reflection Imports Pilz.Reflection.PluginSystem.Attributes Public Class Plugin ''' ''' A collection of Methods that contains PluginFunctions that will be called automatically when loading the Plugin, as long as the property AutoCallMainFunctions is set to True. ''' ''' Public ReadOnly Property MainFunctions As IReadOnlyList(Of PluginFunction) ''' ''' A collection of Methods with a FunctionCode (excluding all PluginFunctions from MainFunctions). ''' ''' Public ReadOnly Property PluginFunctions As IReadOnlyList(Of PluginFunction) ''' ''' Gets the assembly that contains the PluginFunctions of this Plugin ''' ''' Public ReadOnly Property Assembly As Assembly ''' ''' Gets the main module that contains the PluginFunctions of this Plugin ''' ''' Public ReadOnly Property MainModule As Type ''' ''' Load a new Plugin and its PluginFunctions. ''' ''' ''' If true, all MainMethods of a Plugin will be called as soon as a Plugin is loaded. ''' The name of the type where to search for Methods when loading a new Plugin. Public Sub New(filePath As String, autoCallMainFunction As Boolean, entryTypeName As String) Assembly = Assembly.LoadFile(filePath) MainModule = Assembly.GetType(entryTypeName) If MainModule Is Nothing Then Throw New PluginLoadException("Plugin Modul not found!") End If 'Define the attribute types to observe Dim entryMethodType As Type = GetType(LoadMethodAttribute) Dim implementMethodType As Type = GetType(PluginFunctionAttribute) 'Create the lists Dim mainMethods As New List(Of PluginFunction) Dim implementMethods As New List(Of PluginFunction) 'Search for PluginFunctions For Each mi As MethodInfo In MainModule.GetMethods Dim found As Boolean = False 'Check if the method has one of the defined attributes For Each attr As Attribute In Attribute.GetCustomAttributes(mi) If Not found Then Dim t As Type = attr.GetType Select Case t Case entryMethodType mainMethods.Add(New PluginFunction(mi, Me)) Case implementMethodType With CType(attr, PluginFunctionAttribute) implementMethods.Add(New PluginFunction(mi, Me, .Params, .FunctionCode)) End With End Select found = True End If Next Next 'Set the collections Me.MainFunctions = mainMethods Me.PluginFunctions = implementMethods 'Call all PluginFunctions in MainFunctions If autoCallMainFunction Then For Each func As PluginFunction In mainMethods Dim params As ParameterInfo() = func.Method.GetParameters If params.Length = 1 Then Dim startupExe As String = Assembly.GetEntryAssembly.Location Dim args As String() = {startupExe, filePath} func.Invoke({args}) ElseIf Not params.Any Then func.Invoke() End If Next End If End Sub ''' ''' Get all PluginFunctions that have one of the given function codes. ''' ''' ''' Public Function GetFunctions(ParamArray funcCodes As String()) As IEnumerable(Of PluginFunction) Dim funcs As New List(Of PluginFunction) For Each func As PluginFunction In PluginFunctions If funcCodes.Contains(func.FunctionCode) Then funcs.Add(func) End If Next Return funcs End Function ''' ''' Get the first PluginFunction that have the one of the given function codes. ''' ''' Public Function GetFunction(ParamArray funcCodes As String()) As PluginFunction Dim f As PluginFunction = Nothing For Each func As PluginFunction In PluginFunctions If f Is Nothing AndAlso funcCodes.Contains(func.FunctionCode) Then f = func End If Next Return f End Function End Class