1. Code
  2. Coding Fundamentals

Erweitern Sie Ihre .NET-Anwendungen mit Add-Ons

Scroll to top

German (Deutsch) translation by Nikol Angelowa (you can also view the original English article)

Ihrer Anwendung fehlt eine coole Whizbang-Funktion? Lassen Sie andere interessierte Entwickler Ihre Anwendung durch Add-Ons erweitern. Indem Sie Ihre App später für zusätzliche Funktionen öffnen, können Sie eine florierende Community rund um Ihre Anwendung aufbauen, möglicherweise sogar einen Marktplatz!

Im heutigen Tutorial werden wir genau das lernen!


Schritt 0 - Unser Spielplan

Abhängig von der verwendeten Version von Visual Studio und der Version des Frameworks, auf das Sie abzielen, sehen einige Screenshots möglicherweise etwas anders aus.

Wir werden eine Proof-of-Concept-Anwendung erstellen, die beim Start Add-Ons lädt, die in einem ihrer Unterverzeichnisse gefunden werden. Diese Add-Ons sind .NET-Assemblys, die mindestens eine Klasse enthalten, die eine bestimmte von uns definierte Schnittstelle implementiert. Die Konzepte in diesem Lernprogramm sollten ohne großen Aufwand problemlos in Ihre vorhandenen Anwendungen übertragen werden können. Dann sehen wir uns ein vollständigeres Beispiel an, bei dem UI-Komponenten verwendet werden, die von einem Add-On geladen wurden.

Dieses Tutorial wurde mit Microsoft Visual Studio 2010 in VB.NET für .NET Framework 4.0 erstellt. Die wichtigsten Konzepte dieses Tutorials sollten in anderen CLR-Sprachen ab .NET Framework 1.1 funktionieren. Es gibt einige kleinere Funktionen, die in anderen CLR-Sprachen nicht funktionieren - aber sehr einfach zu portieren sein sollten - und einige Konzepte wie Generika, die in .NET 1.1 usw. offensichtlich nicht funktionieren.

Hinweis: Das ist ein Tutorial auf Expertenebene für Benutzer, die mit der Konvertierung von Code zwischen verschiedenen CLR-Sprachen und Versionen des .NET-Frameworks zufrieden sind. Es ist mehr "Ersetzen Ihres Automotors" als "Fahren".


Schritt 1 - Erste Implementierung im kleinen Maßstab

Hinweis: Ihre Referenzen können je nach der Version von .NET Framework, auf die Sie abzielen, unterschiedlich sein.

Beginnen wir mit der Implementierung einer kleinen Version unserer Anwendung. Wir werden drei Projekte in unserer Lösung benötigen:

  • ConsoleAppA: Eine Konsolenanwendung
  • ClassLibA: Eine Klassenbibliothek
  • AddonA: Eine Klassenbibliothek, die als unser Add-On fungiert

Fügen Sie ClassLibA eine Referenz von ConsoleAppA und AddonA hinzu. Der Lösungs-Explorer sollte so aussehen:

Erstellung von der Add-On-Schnittstelle

Damit eine kompilierte Klasse als kompatibel angesehen werden kann, muss jedes Add-On für unsere Anwendung eine bestimmte Schnittstelle implementieren. Diese Schnittstelle definiert die erforderlichen Eigenschaften und Operationen, über die die Klasse verfügen muss, damit unsere Anwendung problemlos mit dem Add-On interagieren kann. Wir könnten auch eine abstract/MustInherit-Klasse als Basis für Add-Ons verwenden, aber in diesem Beispiel verwenden wir eine Schnittstelle.

Hier ist der Code für unsere Schnittstelle, der in einer Datei namens IApplicationModule in der ClassLibA-Klassenbibliothek abgelegt werden sollte.

1
Public Interface IApplicationModule
2
3
    ReadOnly Property Id As Guid
4
    ReadOnly Property Name As String
5
6
    Sub Initialise()
7
8
End Interface

Die Eigenschaften und Methoden, die Sie in der Schnittstelle definieren, sind beliebig. In diesem Fall habe ich zwei Eigenschaften und eine Methode definiert, aber in der Praxis können und sollten Sie sie nach Bedarf ändern.

In unserem ersten Beispiel werden die Eigenschaften Id oder Name nicht verwendet, aber sie sind nützliche Eigenschaften, die implementiert werden müssen. Wenn Sie Add-Ons in der Produktion verwenden, möchten Sie sie vorhanden haben.

Add-On erstellen

Jetzt erstellen wir das eigentliche Add-On. Damit eine Klasse als Add-On für unsere Anwendung betrachtet werden kann, muss sie unsere Schnittstelle - IApplicationModule - implementieren.

Hier ist der Code für unser Basis-Add-On, der in einer Datei namens MyAddonClass in der AddonA-Klassenbibliothek abgelegt werden sollte.

1
Imports ClassLibA
2
3
Public Class MyAddonClass
4
    Implements IApplicationModule
5
6
    Public ReadOnly Property Id As System.Guid Implements ClassLibA.IApplicationModule.Id
7
        Get
8
            Return New Guid("adb86b53-2207-488e-b0f3-ecd13eae4042")
9
        End Get
10
    End Property
11
12
    Public Sub Initialise() Implements ClassLibA.IApplicationModule.Initialise
13
        Console.WriteLine("MyAddonClass is starting up ...")
14
        'Perform start-up initialisation here ...

15
    End Sub
16
17
    Public ReadOnly Property Name As String Implements ClassLibA.IApplicationModule.Name
18
        Get
19
            Return "My first test add-on"
20
        End Get
21
    End Property
22
End Class

Schritt 2 - Suchen von Add-Ons zur Laufzeit

Dann benötigen wir eine Möglichkeit, Add-Ons für unsere Anwendung zu finden. In diesem Beispiel wird davon ausgegangen, dass im Verzeichnis der ausführbaren Datei ein Addons-Ordner erstellt wurde. Wenn Sie dies in Visual Studio testen, berücksichtigen Sie das Standard-Projektausgabeverzeichnis für Projekte, nämlich ./bin/debug/, sodass Sie ein ./bin/debug/Addons/-Verzeichnis benötigen.

Zeit zum Nachdenken

Platzieren Sie die TryLoadAssemblyReference-Methode unten in Module1 von ConsoleAppA. Wir untersuchen die beladene Baugruppe mithilfe von Reflection. Eine Pseudo-Code-exemplarische Vorgehensweise für die Funktionalität lautet wie folgt:

  • Versuchen Sie, den angegebenen dllFilePath als .NET-Assembly zu laden
  • Wenn wir die Assembly erfolgreich geladen haben, fahren Sie fort
  • Für jedes Modul in der geladenen Baugruppe
  • Für jeden Typ in diesem Modul
  • Für jede von diesem Typ implementierte Schnittstelle
  • Wenn diese Schnittstelle unsere Add-On-Schnittstelle (IApplicationModule) ist, dann
  • Führen Sie Aufzeichnungen über diesen Typ. Beenden Sie die Suche.
  • Geben Sie zum Schluss alle gefundenen gültigen Typen zurück
1
    Private Function TryLoadAssemblyReference(ByVal dllFilePath As String) As List(Of System.Type)
2
        Dim loadedAssembly As Assembly
3
        Dim listOfModules As New List(Of System.Type)
4
        Try
5
            loadedAssembly = Assembly.LoadFile(dllFilePath)
6
        Catch ex As Exception
7
        End Try
8
        If loadedAssembly IsNot Nothing Then
9
            For Each assemblyModule In loadedAssembly.GetModules
10
                For Each moduleType In assemblyModule.GetTypes()
11
                    For Each interfaceImplemented In moduleType.GetInterfaces()
12
                        If interfaceImplemented.FullName = "ClassLibA.IApplicationModule" Then
13
                            listOfModules.Add(moduleType)
14
                        End If
15
                    Next
16
                Next
17
            Next
18
        End If
19
        Return listOfModules
20
    End Function

Starten Sie unsere Add-Ons

Schließlich können wir jetzt eine kompilierte Klasse laden, die unsere Schnittstelle in den Speicher implementiert. Wir haben jedoch keinen Code, um diese Klassen zu finden, zu instanziieren oder Methodenaufrufe durchzuführen. Als nächstes werden wir einen Code zusammenstellen, der genau das tut.

Der erste Teil besteht darin, alle Dateien zu finden, bei denen es sich möglicherweise um Add-Ons handelt (siehe unten). Der Code führt eine relativ einfache Dateisuche durch und versucht für jede gefundene DLL-Datei, alle gültigen Typen aus dieser Assembly zu laden. DLLs, die im Ordner "Addons" gefunden wurden, sind nicht unbedingt Add-Ons. Sie können lediglich zusätzliche Funktionen enthalten, die für ein Add-On erforderlich sind, sind jedoch an sich kein Add-On.

1
        Dim currentApplicationDirectory As String = My.Application.Info.DirectoryPath
2
        Dim addonsRootDirectory As String = currentApplicationDirectory & "\Addons\"
3
        Dim addonsLoaded As New List(Of System.Type)
4
5
        If My.Computer.FileSystem.DirectoryExists(addonsRootDirectory) Then
6
            Dim dllFilesFound = My.Computer.FileSystem.GetFiles(addonsRootDirectory, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.dll")
7
            For Each dllFile In dllFilesFound
8
                Dim modulesFound = TryLoadAssemblyReference(dllFile)
9
                addonsLoaded.AddRange(modulesFound)
10
            Next
11
        End If

Dann müssen wir für jeden gültigen Typ, den wir gefunden haben, etwas tun. Der folgende Code erstellt eine neue Instanz des Typs, gibt den Typ ein, ruft die Initialise()-Methode auf (dies ist nur eine beliebige Methode, die wir in unserer Schnittstelle definiert haben) und behält dann einen Verweis auf diesen instanziierten Typ in einer Liste auf Modulebene bei .

1
        If addonsLoaded.Count > 0 Then
2
            For Each addonToInstantiate In addonsLoaded
3
                Dim thisInstance = Activator.CreateInstance(addonToInstantiate)
4
                Dim thisTypedInstance = CType(thisInstance, ClassLibA.IApplicationModule)
5
                thisTypedInstance.Initialise()
6
                m_addonInstances.Add(thisInstance)
7
            Next
8
        End If

Alles in allem sollte unsere Konsolenanwendung ungefähr so aussehen:

1
Imports System.Reflection
2
3
Module Module1
4
5
    Private m_addonInstances As New List(Of ClassLibA.IApplicationModule)
6
7
    Sub Main()
8
        LoadAdditionalModules()
9
10
        Console.WriteLine('Finished loading modules ...')

11
        Console.ReadLine()
12
    End Sub
13
14
    Private Sub LoadAdditionalModules()
15
        Dim currentApplicationDirectory As String = My.Application.Info.DirectoryPath
16
        Dim addonsRootDirectory As String = currentApplicationDirectory & '\Addons\'

17
        Dim addonsLoaded As New List(Of System.Type)
18
19
        If My.Computer.FileSystem.DirectoryExists(addonsRootDirectory) Then
20
            Dim dllFilesFound = My.Computer.FileSystem.GetFiles(addonsRootDirectory, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.dll")
21
            For Each dllFile In dllFilesFound
22
                Dim modulesFound = TryLoadAssemblyReference(dllFile)
23
                addonsLoaded.AddRange(modulesFound)
24
            Next
25
        End If
26
27
        If addonsLoaded.Count > 0 Then
28
            For Each addonToInstantiate In addonsLoaded
29
                Dim thisInstance = Activator.CreateInstance(addonToInstantiate)
30
                Dim thisTypedInstance = CType(thisInstance, ClassLibA.IApplicationModule)
31
                thisTypedInstance.Initialise()
32
                m_addonInstances.Add(thisInstance)
33
            Next
34
        End If
35
    End Sub
36
37
    Private Function TryLoadAssemblyReference(ByVal dllFilePath As String) As List(Of System.Type)
38
        Dim loadedAssembly As Assembly
39
        Dim listOfModules As New List(Of System.Type)
40
        Try
41
            loadedAssembly = Assembly.LoadFile(dllFilePath)            
42
        Catch ex As Exception
43
        End Try
44
        If loadedAssembly IsNot Nothing Then
45
            For Each assemblyModule In loadedAssembly.GetModules
46
                For Each moduleType In assemblyModule.GetTypes()
47
                    For Each interfaceImplemented In moduleType.GetInterfaces()
48
                        If interfaceImplemented.FullName = 'ClassLibA.IApplicationModule' Then

49
                            listOfModules.Add(moduleType)
50
                        End If
51
                    Next
52
                Next
53
            Next
54
        End If
55
        Return listOfModules
56
    End Function
57
End Module

Probelauf

Zu diesem Zeitpunkt sollten wir in der Lage sein, einen vollständigen Build unserer Lösung durchzuführen. Wenn Ihre Dateien erstellt wurden, kopieren Sie die kompilierte Assembly-Ausgabe des AddonA-Projekts in den Addons-Ordner von ConsoleAppA. Der Addons-Ordner sollte unter dem Ordner /bin/debug/ erstellt werden. Auf meinem Computer mit Visual Studio 2010, Standardprojektspeicherorten und einer Lösung namens "DotNetAddons" befindet sich der Ordner hier:

C:\Users\jplenderleith\Documents\Visual Studio 2010\Projects\DotNetAddons\ConsoleAppA\bin\Debug\Addons

Wir sollten die folgende Ausgabe sehen, wenn wir den Code ausführen:

1
MyAddonClass is starting up ...
2
Finished loading modules ...

So wie es aussieht, ist es nicht auffällig oder beeindruckend, aber es zeigt eine wichtige Funktionalität, nämlich, dass wir zur Laufzeit eine Assembly abrufen und Code innerhalb dieser Assembly ausführen können, ohne über vorhandene Kenntnisse über diese Assembly zu verfügen. Dies ist die Grundlage für die Erstellung komplexerer Add-Ons.


Schritt 3 - Integration in eine Benutzeroberfläche

Als Nächstes werden einige Add-Ons erstellt, um zusätzliche Funktionen in einer Windows Forms-Anwendung bereitzustellen.

Erstellen Sie ähnlich wie bei der vorhandenen Lösung eine neue Lösung mit den folgenden Projekten:

  • WinFormsAppA: Eine Windows Forms-Anwendung
  • ClassLibA: Eine Klassenbibliothek
  • UIAddonA: Eine Klassenbibliothek, die einige Add-Ons mit UI-Komponenten enthält

Ähnlich wie bei unserer vorherigen Lösung sollten sowohl die WinFormsAppA- als auch die UIAddonA-Projekte Verweise auf die ClassLibA enthalten. Das UIAddonA-Projekt benötigt außerdem einen Verweis auf System.Windows.Forms, um auf Funktionen zugreifen zu können.

Die Windows Forms-Anwendung

Wir erstellen eine schnelle und einfache Benutzeroberfläche für unsere Anwendung, die aus einem MenuStrip und einem DataGridView besteht. Das MenuStrip-Steuerelement sollte drei MenuItems haben

  • Datei
  • Add-Ons
  • Hilfe

Docken Sie die DataGridView an ihren übergeordneten Container an - das Formular selbst. Wir werden einen Code zusammenstellen, um einige Scheindaten in unserem Raster anzuzeigen. Das Add-Ons-Menüelement wird mit allen Add-Ons gefüllt, die beim Start der Anwendung geladen wurden.

Hier ist ein Screenshot der Anwendung zu diesem Zeitpunkt:

Schreiben wir einen Code, um der Hauptform von WinFormsAppA einige Funktionen zu geben. Wenn das Formular geladen wird, wird die derzeit leere LoadAddons()-Methode aufgerufen - wir werden dies später ausfüllen. Anschließend generieren wir einige Beispieldaten von Mitarbeitern, an die wir unser DataGridView binden.

1
Public Class Form1
2
3
    Private m_testDataSource As DataSet
4
    Private m_graphicalAddons As List(Of System.Type)
5
6
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
7
        LoadAddons()
8
        m_testDataSource = GenerateTestDataSet()
9
        With DataGridView1
10
            .AutoGenerateColumns = True
11
            .AutoResizeColumns()
12
            .DataSource = m_testDataSource.Tables(0)
13
        End With
14
    End Sub
15
16
    Private Sub LoadAddons()        
17
18
    End Sub
19
20
    Private Function GenerateTestDataSet() As DataSet
21
        Dim newDataSet As New DataSet
22
        Dim newDataTable As New DataTable
23
        Dim firstNames = {"Mary", "John", "Paul", "Justyna", "Michelle", "Andrew", "Michael"}
24
        Dim lastNames = {"O'Reilly", "Murphy", "Simons", "Kelly", "Gates", "Power"}
25
        Dim deptNames = {"Marketing", "Sales", "Technical", "Secretarial", "Security"}
26
27
        With newDataTable
28
            .Columns.Add("EmployeeId", GetType(Integer))
29
            .Columns.Add("Name", GetType(String))
30
            .Columns.Add("IsManager", GetType(Boolean))
31
            .Columns.Add("Department", GetType(String))
32
        End With
33
34
        For i = 1 To 100
35
            Dim newDataRow As DataRow = newDataTable.NewRow()
36
            With newDataRow
37
                .Item("EmployeeId") = i
38
                .Item("Name") = firstNames(i Mod firstNames.Count) & " " & lastNames(i Mod lastNames.Count)
39
                .Item("IsManager") = ((i Mod 20) = 0)
40
                .Item("Department") = deptNames(i Mod deptNames.Count)
41
            End With
42
            newDataTable.Rows.Add(newDataRow)
43
        Next
44
45
        newDataSet.Tables.Add(newDataTable)
46
        Return newDataSet
47
    End Function
48
49
End Class

Wenn wir die Anwendung ausführen, sollte sie folgendermaßen aussehen:

Nachdem wir die Add-On-Schnittstellen definiert haben, kehren wir zu unseren leeren LoadAddons() zurück.

Add-On-Schnittstelle

Definieren wir unsere Add-On-Oberfläche. UI-Komponenten werden unter Add-ons MenuStrip aufgelistet und öffnen ein Windows-Formular, das Zugriff auf die Daten hat, an die unser DataGrid gebunden ist. Fügen Sie dem ClassLibA-Projekt eine neue Schnittstellendatei mit dem Namen IGraphicalAddon hinzu und fügen Sie den folgenden Code in die Datei ein:

1
Public Interface IGraphicalAddon
2
3
    ReadOnly Property Name As String
4
    WriteOnly Property DataSource As DataSet
5
    Sub OnClick(ByVal sender As Object, ByVal e As System.EventArgs)
6
7
End Interface
  • Wir haben eine Name-Eigenschaft, die ziemlich selbsterklärend ist.
  • Die DataSource wird ordnungsgemäß verwendet, um Daten an dieses Add-On weiterzuleiten.
  • Die OnClick-Methode, die als Handler verwendet wird, wenn Benutzer auf den Eintrag unseres Add-Ons im Menü Addons klicken.

Laden der Add-Ons

Fügen Sie dem ClassLibA-Assemblyprojekt eine Klassenbibliothek mit dem Namen AddonLoader mit dem folgenden Code hinzu:

1
Imports System.Reflection
2
3
Public Class AddonLoader
4
    Public Enum AddonType
5
        IGraphicalAddon = 10
6
        ISomeOtherAddonType2 = 20
7
        ISomeOtherAddonType3 = 30
8
    End Enum
9
10
    Public Function GetAddonsByType(ByVal addonType As AddonType) As List(Of System.Type)
11
        Dim currentApplicationDirectory As String = My.Application.Info.DirectoryPath
12
        Dim addonsRootDirectory As String = currentApplicationDirectory & "\Addons\"
13
        Dim loadedAssembly As Assembly
14
        Dim listOfModules As New List(Of System.Type)
15
16
        If My.Computer.FileSystem.DirectoryExists(addonsRootDirectory) Then
17
            Dim dllFilesFound = My.Computer.FileSystem.GetFiles(addonsRootDirectory, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.dll")
18
            For Each dllFile In dllFilesFound
19
20
                Try
21
                    loadedAssembly = Assembly.LoadFile(dllFile)
22
                Catch ex As Exception
23
                End Try
24
                If loadedAssembly IsNot Nothing Then
25
                    For Each assemblyModule In loadedAssembly.GetModules
26
                        For Each moduleType In assemblyModule.GetTypes()
27
                            For Each interfaceImplemented In moduleType.GetInterfaces()
28
                                If interfaceImplemented.Name = addonType.ToString Then
29
                                    listOfModules.Add(moduleType)
30
                                End If
31
                            Next
32
                        Next
33
                    Next
34
                End If
35
36
            Next
37
        End If
38
39
        Return listOfModules
40
    End Function
41
End Class

Sie können ähnlichen Code verwenden, um Add-On-Entwickler darauf zu beschränken, nur bestimmte Arten von Add-Ons zu erstellen

In dieser Klasse haben wir eine Möglichkeit bereitgestellt, verschiedene Arten von Add-Ons zu laden. Sie können ähnlichen Code verwenden, um Add-On-Entwickler darauf zu beschränken, nur bestimmte Arten von Add-Ons zu erstellen oder sie zumindest zu kategorisieren. In unserem Beispiel verwenden wir nur den ersten deklarierten Add-On-Typ, nämlich IGraphicalAddon.

Wenn wir andere Add-On-Typen in unserem Projekt hatten, um beispielsweise die Berichtsfunktionalität zu verbessern oder einige nützliche Tastaturkürzel bereitzustellen, möchten wir nicht, dass diese in unserem Add-On-Menü aufgeführt werden, da es keinen Sinn macht, dass jemand darauf klicken kann auf diesem Add-On.

Allerdings kann es wünschenswert sein, in einer Menüleiste einen Verweis auf alle Add-Ons hinzuzufügen. Klicken Sie auf, um das Optionsformular des Add-Ons anzuzeigen. Dies würde jedoch den Rahmen dieses Tutorials sprengen.

Das grafische Add-On

Lassen Sie uns das eigentliche UI-Add-On erstellen. Fügen Sie dem UIAddonA-Assemblyprojekt die folgenden zwei Dateien hinzu. eine Klasse namens UIReportAddon1 und ein Windows-Formular namens UIReportAddon1Form. Die UIReportAddon1-Klasse enthält den folgenden Code:

1
Imports ClassLibA
2
3
Public Class UIReportAddon1
4
    Implements ClassLibA.IGraphicalAddon
5
6
    Private _dataSource As DataSet
7
    Public WriteOnly Property DataSource As System.Data.DataSet Implements IGraphicalAddon.DataSource
8
        Set(ByVal value As System.Data.DataSet)
9
            _dataSource = value
10
        End Set
11
    End Property
12
13
    Public ReadOnly Property Name As String Implements IGraphicalAddon.Name
14
        Get
15
            Return "Managers Report"
16
        End Get
17
    End Property
18
19
    Public Sub OnClick(ByVal sender As Object, ByVal e As System.EventArgs) Implements IGraphicalAddon.OnClick
20
        Dim newUiReportingAddonForm As New UIReportAddon1Form
21
        newUiReportingAddonForm.SetData(_dataSource)
22
        newUiReportingAddonForm.ShowDialog()
23
    End Sub
24
End Class

Fügen Sie UIReportAddon1Form eine DataGridView hinzu, die in ihrem übergeordneten Container angedockt ist. Fügen Sie dann den folgenden Code hinzu:

1
Public Class UIReportAddon1Form
2
3
    Private m_providedDataSource As DataSet
4
5
    Public Sub SetData(ByVal DataSource As System.Data.DataSet)
6
        m_providedDataSource = DataSource
7
        FilterAndShowData()
8
    End Sub
9
10
    Private Sub FilterAndShowData()
11
        Dim managers = m_providedDataSource.Tables(0).Select("IsManager = True")
12
        Dim newDataTable = m_providedDataSource.Tables(0).Clone
13
        For Each dr In managers
14
            newDataTable.ImportRow(dr)
15
        Next
16
        DataGridView1.DataSource = newDataTable
17
    End Sub
18
19
    Private Sub UIReportAddon1Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
20
        Text = "List of managers"
21
    End Sub
22
End Class

Wir bieten lediglich die Möglichkeit, Daten an das Formular zu senden und es dann entscheiden zu lassen, was mit diesen Daten geschehen soll. In diesem Fall führen wir Select() für eine DataTable aus und rufen eine Liste aller Mitarbeiter ab, die Manager sind.

Zurück zu unserer Hauptbenutzeroberfläche

Jetzt ist es Zeit, unsere unvollendete LoadAddons()-Methode in unserem WinFormsAppA-Projekt abzuschließen. Dieser Code weist die GetAddonsByType-Methode von ClassLibA.AddonLoader an, einen bestimmten Add-On-Typ zu finden - in diesem Fall IGraphicalAddon-Add-Ons.

Für jedes gefundene Add-On werden die folgenden Aktionen ausgeführt

  • Erstellen Sie eine neue Instanz des Add-Ons
  • Geben Sie die Add-On-Instanz zu IGraphicalAddon ein
  • Füllen Sie die DataSource-Eigenschaft aus
  • Fügen Sie das Add-On zum Menüpunkt Add-Ons hinzu
  • Fügen Sie einen Handler für das Click-Ereignis dieses Menüelements hinzu
1
    Private Sub LoadAddons()
2
        Dim loader As New ClassLibA.AddonLoader
3
        Dim addonsLoaded = loader.GetAddonsByType(ClassLibA.AddonLoader.AddonType.IGraphicalAddon)
4
5
        For Each graphicalAddon In addonsLoaded
6
            Dim thisInstance = Activator.CreateInstance(graphicalAddon)
7
            Dim typedAddon = CType(thisInstance, ClassLibA.IGraphicalAddon)
8
            typedAddon.DataSource = m_testDataSource
9
            Dim newlyAddedToolstripItem = AddonsToolStripMenuItem.DropDownItems.Add(typedAddon.Name)
10
            AddHandler newlyAddedToolstripItem.Click, AddressOf typedAddon.OnClick
11
        Next
12
    End Sub

Testen unserer Benutzeroberfläche

Stellen Sie sicher, dass Sie eine vollständige erfolgreiche Kompilierung der Lösung durchführen können. Kopieren Sie die Datei UIAddonA.dll aus dem Ausgabe-Debug-Ordner des UIAddonA-Projekts in den Ordner /bin/debug/Addons/ des WinFormsAppA-Projekts. Wenn Sie das Projekt ausführen, sollten Sie, wie zuvor, ein Datenraster sehen. Wenn Sie jedoch in das Menü Add-Ons klicken, sollte jetzt ein Verweis auf das neu erstellte Add-On angezeigt werden.

Wenn wir auf den Menüpunkt Managerbericht klicken, wird ein Methodenaufruf für die in unserem Add-On implementierte OnClick-Methode ausgeführt, wodurch UIReportAddon1Form so angezeigt wird.


Abschluss

Wir haben zwei Beispiele für die Erstellung einer Anwendung gesehen, mit der Add-Ons nach Bedarf abgerufen und ausgeführt werden können. Wie bereits erwähnt, sollte es einfach genug sein, diese Art von Funktionalität in vorhandene Anwendungen zu integrieren. Die Frage, wie viel Kontrolle Sie benötigen (oder wollen), um Entwicklern von Drittanbietern zu geben, ist eine ganz andere Frage.

Ich hoffe Sie haben Spaß mit diesem Tutorial! Vielen Dank fürs Lesen!