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.
Each of the listed strategies is an instance of a plug-in which are loaded dynamically at Form_Load.
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.
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...