Die Community zu .NET und Classic VB.
Menü

Tipp-Upload: VB.NET 0230: Rechner mit Plugin Schnittstelle

 von 

Hinweis zum Tippvorschlag  

Dieser Vorschlag wurde noch nicht auf Sinn und Inhalt überprüft und die Zip-Datei wurde noch nicht auf schädlichen Inhalt hin untersucht.
Bitte haben Sie ein wenig Geduld, bis die Freigabe erfolgt.

Über den Tipp  

Dieser Tippvorschlag ist noch unbewertet.

Der Vorschlag ist in den folgenden Kategorien zu finden:

  • Sonstiges

Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Rechner, Plugin, Schnittstelle, Reflection

Der Vorschlag wurde erstellt am: 15.03.2008 12:00.
Die letzte Aktualisierung erfolgte am 15.03.2008 12:00.

Zurück zur Übersicht

Beschreibung  

Dieser Tipp zeigt am Beispiel eines Rechners, wie man eine Plugin-Schnittstelle in sein Projekt einbaut.

Schwierigkeitsgrad

Schwierigkeitsgrad 3

Verwendete API-Aufrufe:

Download:

Download des Beispielprojektes [40,91 KB]

' Dieser Source stammt von http://www.activevb.de
' und kann frei verwendet werden. Für eventuelle Schäden
' wird nicht gehaftet.

' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
' Ansonsten viel Spaß und Erfolg mit diesem Source!
'
' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird.
' In den Zip-Dateien ist er jedoch zu finden.

' -------- Anfang Projektgruppe Plugin Calculator.sln --------
' ------- Anfang Projektdatei Plugin Calculator.vbproj -------
' ----------------- Anfang Datei MainForm.vb -----------------
Imports PluginCalculator.Plugins
Imports System.Reflection
Imports System.IO

Public Class MainForm

    Private plugins As New List(Of Plugin)() ' Liste mit allen geladenen Plugins

    Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles MyBase.Load

        Me.LoadPlugins() ' Plugins laden

    End Sub

    ''' <summary>
    ''' Lädt alle Plugins aus dem Standard Pluginsverzeichnis.
    ''' </summary>
    Private Sub LoadPlugins()

        Dim path As String = GetPluginsDirectory() ' Pluginverzeichnis ermitteln

        ' Durch .dll-Dateien in Pluginsverzeichnis iterieren
        For Each file As FileInfo In New DirectoryInfo(path).GetFiles("*.dll")
            Try

                For Each plugin As Plugin In Me.GetPlugins(file.FullName) ' Durch
                                                                          ' instanzierte
                                                                          ' Plugins
                                                                          ' iterieren
                    Me.LoadPlugin(plugin) ' Plugin laden
                Next

            Catch ex As Exception ' Bei Ausnahmen Fehlermeldung anzeigen

                MessageBox.Show("Plugin """ & file.Name & """ konnte nicht geladen " & _
                    "werden:" & vbNewLine & "  " & ex.Message, "Plugin Calculator", _
                    MessageBoxButtons.OK, MessageBoxIcon.Error)

            End Try

        Next

    End Sub

    ''' <summary>
    ''' Lädt ein Plugin in die Pluginliste der Form und in das Operator Auswahlmenü.
    ''' </summary>
    ''' <param name="plugin">Das zu ladende Plugin.</param>
    Private Sub LoadPlugin(ByVal plugin As Plugin)

        ' Wenn kein Plugin mit dem gleichen Operator bereits geladen ist
        If Not Me.plugins.Exists(Function(x As Plugin) x.OperatorName = plugin.OperatorName) Then
            Me.plugins.Add(plugin) ' Plugin zu Liste hinzufügen
            Me.OperatorComboBox.Items.Add(plugin.OperatorName) ' Operator zu Dropdown-Menü
                                                               ' hinzufügen

            Me.CalculateButton.Enabled = True ' Berechnen-Button aktivieren, da jetzt
                                              ' mindestens ein Plugin geladen
            Me.OperatorComboBox.SelectedIndex = 0 ' Ersten Operator auswählen

        Else ' Wenn Plugin mit gleichem Operator bereits geladen, Fehlermeldung anzeigen

            MessageBox.Show("Ein Plugin mit dem Operator """ & plugin.OperatorName & """ " & _
                "ist bereits geladen.", "Plugin Calculator", MessageBoxButtons.OK, _
                MessageBoxIcon.Error)

        End If

    End Sub

    ''' <summary>
    ''' Instanziert alle Plugins aus einer Pluginassembly.
    ''' </summary>
    ''' <param name="path">Der Pfad zur Pluginassembly.</param>
    Private Shared Function GetPlugins(ByVal path As String) As List(Of Plugin)

        Dim ass = Assembly.LoadFile(path) ' Assembly (DLL) laden
        Dim plugins As New List(Of Plugin)() ' Liste mit allen geladenen Plugins

        For Each tp As Type In ass.GetTypes() ' Durch alle Typen (Klassen) in der Assembly iterieren

            If tp.GetInterfaces().Contains(GetType(Plugin)) Then ' Wenn Typ Plugin implementiert

                ' Plugin instanzieren
                Dim instance = DirectCast(Activator.CreateInstance(tp), Plugin)
                plugins.Add(instance) ' Plugin zu Liste hinzufügen
            End If

        Next

        Return plugins ' Liste zurückgeben

    End Function

    ''' <summary>
    ''' Gibt das Pluginstandardverzeichnis zurück
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Shared Function GetPluginsDirectory() As String

        ' Pfad zusammenstellen
        Dim path = IO.Path.Combine(Application.CommonAppDataPath, "plugins")
        If Not Directory.Exists(path) Then Directory.CreateDirectory(path) ' Ggf.
                                                                           ' Verzeichnis
                                                                           ' erstellen
        Return path ' Pfad zurückgeben

    End Function

    Private Sub InstallPluginButton_Click(ByVal sender As System.Object, ByVal e As _
        System.EventArgs) Handles InstallPluginButton.Click

        If Me.OpenFileDialog.ShowDialog() = DialogResult.OK Then ' Wenn im
                                                                 ' Dateiauswahldialog auf OK
                                                                 ' geklickt

            Try

                GetPlugins(Me.OpenFileDialog.FileName) ' Assembly laden und Plugins
                                                       ' instanzieren, um Assembly zu
                                                       ' validieren

                ' Zielpfad des Plugins
                Dim targetPath = Path.Combine(GetPluginsDirectory(), Path.GetFileName( _
                    Me.OpenFileDialog.FileName))

                Dim i As Integer = 2

                Do While File.Exists(targetPath) ' Wenn Zieldatei bereits existiert, hinter
                                                 ' Dateinamen Zähler einfügen und hochzählen
                                                 ' Bsp: meinplugin (2).dll

                    targetPath = Path.Combine(GetPluginsDirectory(), _
                        Path.GetFileNameWithoutExtension(Me.OpenFileDialog.FileName)) & " " & _
                        "(" & i.ToString() & ").dll"

                    i += 1
                Loop

                File.Copy(Me.OpenFileDialog.FileName, targetPath) ' Datei kopieren

                Dim plugins = GetPlugins(targetPath) ' Plugins instanzieren

                For Each plugin As Plugin In plugins ' Plugins laden
                    Me.LoadPlugin(plugin)
                Next

            Catch ex As Exception ' Bei Ausnahmen Fehlermeldung anzeigen

                MessageBox.Show("Plugin konnte nicht installiert werden:" & vbNewLine & " " & _
                    " " & ex.Message, "Plugin Calculator", MessageBoxButtons.OK, _
                    MessageBoxIcon.Error)

            End Try
        End If

    End Sub

    Private Sub TextBox_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles XTextBox.Leave, YTextBox.Leave

        Dim tb = DirectCast(sender, TextBox) ' Sender auf TextBox casten

        If tb.Text = "" Then tb.Text = "0" ' Wenn TextBox leer, Text auf 0 setzen
        If Not Double.TryParse(tb.Text, 0) Then ' Wenn Inhalt keine gültige Zahl
            tb.Focus() ' TextBox wieder fokussieren
            Beep() ' Signalton ausgeben
            tb.SelectAll() ' TextBox-Inhalt markieren
        End If

    End Sub

    Private Sub CalculateButton_Click(ByVal sender As System.Object, ByVal e As _
        System.EventArgs) Handles CalculateButton.Click

        Dim x, y As Double

        ' Inhalte der TextBoxen parsen; wenn Inhalt ungültig, abbrechen
        If Not Double.TryParse(Me.XTextBox.Text, x) OrElse Not Double.TryParse( _
            Me.YTextBox.Text, y) Then Return

        Try

            ' Berechnung durchführen
            Me.ResultLabel.Text = Me.plugins(Me.OperatorComboBox.SelectedIndex).Calculate(x, _
                y).ToString()

        Catch ex As Exception ' Bei Ausnahmen Fehlermeldung anzeigen

            MessageBox.Show("Berechnung konnte nicht durchgeführt werden:" & vbNewLine & _
                "  " & ex.Message, "Plugin Calculator", MessageBoxButtons.OK, _
                MessageBoxIcon.Error)

        End Try

    End Sub

End Class

' ------------------ Ende Datei MainForm.vb ------------------
' ----------------- Anfang Datei Program.vb  -----------------
Module Program

    Sub Main()

        Application.EnableVisualStyles()
        Application.Run(New MainForm())

    End Sub

End Module

' ------------------ Ende Datei Program.vb  ------------------
' -------- Ende Projektdatei Plugin Calculator.vbproj --------
' ------- Anfang Projektdatei Plugin Interface.vbproj  -------
' ------------------ Anfang Datei Plugin.vb ------------------
''' <summary>
''' Definiert Funktionen, die von einem Plugin implementiert werden müssen
''' </summary>
''' <remarks></remarks>
Public Interface Plugin

    ''' <summary>
    ''' Führt die Berechnung durch.
    ''' </summary>
    ''' <param name="x">1. Wert</param>
    ''' <param name="y">2. Wert</param>
    Function Calculate(ByVal x As Double, ByVal y As Double) As Double

    ''' <summary>
    ''' Gibt den im Dropdownmenü anzuzeigenden Operatornamen zurück
    ''' </summary>
    ReadOnly Property OperatorName() As String

End Interface

' ------------------- Ende Datei Plugin.vb -------------------
' -------- Ende Projektdatei Plugin Interface.vbproj  --------
' -------- Anfang Projektdatei Default Plugins.vbproj --------
' ----------------- Anfang Datei Plugins.vb  -----------------
Imports PluginCalculator.Plugins

''' <summary>
''' Summenplugin
''' </summary>
Public Class Sum  ' Plugin implementieren

    Implements Plugin

    Public Function Calculate(ByVal x As Double, ByVal y As Double) As Double Implements _
        Plugins.Plugin.Calculate

        Return x + y ' Berechnung durchführen

    End Function

    Public ReadOnly Property OperatorName() As String Implements Plugins.Plugin.OperatorName
        Get
            Return "+" ' Operator zurückgeben

        End Get

    End Property

End Class

Public Class Difference

    Implements Plugin

    Public Function Calculate(ByVal x As Double, ByVal y As Double) As Double Implements _
        Plugins.Plugin.Calculate

        Return x - y

    End Function

    Public ReadOnly Property OperatorName() As String Implements Plugins.Plugin.OperatorName
        Get
            Return "-"

        End Get

    End Property

End Class

Public Class Product

    Implements Plugin

    Public Function Calculate(ByVal x As Double, ByVal y As Double) As Double Implements _
        Plugins.Plugin.Calculate

        Return x * y

    End Function

    Public ReadOnly Property OperatorName() As String Implements Plugins.Plugin.OperatorName
        Get
            Return "*"

        End Get

    End Property

End Class

Public Class Quotient

    Implements Plugin

    Public Function Calculate(ByVal x As Double, ByVal y As Double) As Double Implements _
        Plugins.Plugin.Calculate

        If y = 0 Then Throw New Exception("Division durch 0")

        Return x / y

    End Function

    Public ReadOnly Property OperatorName() As String Implements Plugins.Plugin.OperatorName
        Get
            Return "/"

        End Get

    End Property

End Class

' ------------------ Ende Datei Plugins.vb  ------------------
' --------- Ende Projektdatei Default Plugins.vbproj ---------
' --------- Ende Projektgruppe Plugin Calculator.sln ---------

	

Diskussion  

Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.

Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.