SCProject.Biz CODER logoAverage Strategies - Plugin Version




This is an Average Strategies app, that uses dynamic plug-ins. Each strategy provides a method to calculate a different type of mathematical average, using a unique formula.



Average Strategies



Each of the listed strategies is an instance of a plug-in which are loaded dynamically at Form_Load.



plugins folder



Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim pluginList As New List(Of iPlugin)
    Dim plugins = Directory.GetFiles("plugins", "*.dll")

    For Each plugin In plugins
        Dim assem = Assembly.LoadFrom(plugin)
        For Each t In assem.DefinedTypes()
            If t.GetInterface("iPlugin") IsNot Nothing Then
                Dim inst = DirectCast(assem.CreateInstance(t.FullName), iPlugin)
                pluginList.Add(inst)
                If Not lastNumbers.ContainsKey(inst.inputFormat) Then
                    lastNumbers.Add(inst.inputFormat, New Object() {})
                End If
            End If
        Next
    Next
    ListBox2.DisplayMember = "displayString"
    ListBox2.DataSource = pluginList
    Me.KeyPreview = True

    'https://en.wikipedia.org/wiki/Average
End Sub


Most of the data input is entered in frmMain, except for two of the strategies, which both use a different custom editor. These custom items editors are included as a part of the individual compiled strategy DLL.



Weighted Average



Weighted Average



Each DLL must include a class that implements the shared iPlugin interface. All the main application code in the main GUI form knows of the fourteen strategies is that they all implement the shared iPlugin interface. All interaction between the form and the plug-ins is conducted via the iPlugin interface.



Public Interface iPlugin

    Function SupportsCustomItemsEditor() As Boolean
    Function showCustomEditor(numbers() As Object) As Object()
    Function computeAverage(numbers() As Object) As Object
    ReadOnly Property displayString As String
    ReadOnly Property inputFormat As String

End Interface


This application architecture allows extending the application without rewriting it. All that is necessary to extend the app. is to place a compiled DLL that includes a class that implements the iPlugin interface in the plugins folder.



Imports [Shared]
Imports System.Windows.forms
Public Class WeightedMean
    Implements iPlugin

    Public ReadOnly Property inputFormat As String Implements iPlugin.inputFormat
        Get
            Return "# {#}"
        End Get
    End Property

    Public ReadOnly Property displayString As String Implements iPlugin.displayString
        Get
            Return "Weighted mean"
        End Get
    End Property

    Public Function SupportsCustomItemsEditor() As Boolean Implements iPlugin.SupportsCustomItemsEditor
        Return True
    End Function

    Public Function showCustomEditor(numbers() As Object) As Object() Implements iPlugin.showCustomEditor
        Dim frm As New frmWeights(numbers)
        If frm.ShowDialog = DialogResult.OK Then
            If frm.ListBox1.Items.Count > 0 Then
                Return frm.ListBox1.Items.Cast(Of Object).ToArray
            Else
                Return New Object() {}
            End If
        Else
            Return Nothing
        End If
    End Function

    Public Function computeAverage(numbers() As Object) As Object Implements iPlugin.computeAverage
        Dim numbersAsDecimal(numbers.Length) As Decimal
        Dim weightings(numbers.Length) As Decimal
        Dim sum As Decimal

        For x As Integer = 0 To numbers.GetUpperBound(0)
            Dim parts() As String = numbers(x).ToString.Split(New String() {"   {", "}"}, StringSplitOptions.None)
            numbersAsDecimal(x) = CDec(parts(0))
            weightings(x) = CDec(parts(1))
            sum += numbersAsDecimal(x) * weightings(x)
        Next

        Return sum / weightings.Sum
    End Function
End Class






Download here: Average Strategies - Plugin Version

You need to rebuild the entire solution before you try running the application...