[.Net] Créer et utiliser des plugins dans une application DotNet

dotnet plugins

Aujourd’hui j’ai développé un système de gestion de plugins en DotNet.

En effet, plus je développe et plus je m’aperçois que j’ai souvent le même besoin: pouvoir importer des assembly à un moment précis et permettre à mes collaborateurs de développer leur propres extensions et de les utiliser quand ils le souhaitent.

J’ai donc effectué pas mal de recherche sur le chargement dynamique des assembly et des bibliothèques de fonctionnalités et très vite je suis tombé sur des demandes de tierses personnes qui souhaitaient mettre en place un système de plugins en C# ou VB.Net.

Imaginez une application dans laquelle vous offrez la possibilité à ses utilisateurs d’étendre facilement les fonctionnalités. Que du bonheur!

Nous allons voir comment mettre en place la création et le chargement des plugins au sein de votre application DotNet.

Principe de fonctionnement

Le principe de fonctionnement du système de plugins est plutôt simple: votre programme va référencer une interface qui sera partagée avec le plugin.

Le fait d’utiliser une interface va nous permettre de définir un gabarit de classe qui sera vide mais sur lequel pourra se baser votre programme lors du chargement dynamique de vos DLL de plugins.

Le gros avantage de la plateforme DotNet est qu’il est possible de créer une solution avec plusieurs projets et de référencer un projet directement dans un autre, ce qui est très pratique lorsque vous êtes en cours de développement.

Un fois l’interface référencée, nous allons pouvoir charger dynamiquement la DLL du plugin afin de pouvoir l’utiliser.

L’interface de base du plugin

Comme je vous le disais, nos plugins implémenteront une interface qui sera référencée dans notre application principale.

Voici l’interface que j’utilise pour mon système de plugins en .Net. Plutôt simple non :p

Public Interface IPlugin
    Function Hello() As String
End Interface

Création du plugin

Une fois notre interface définie, on va créer notre plugin:

'/!\ Il faut absolument ajouter une reference au projet PluginInterface qui est l'interface utilisée par la DLL
Imports PluginInterface
 
Public Class MaClass1
    Implements IPlugin
 
    Private mName As String
 
    Public Function Hello() As String Implements IPlugin.Hello
        Return "DLL 1"
    End Function
End Class

Encore une fois, le code est simple et l’implémentation de l’interface nous génère automatiquement l’ensemble des fonctions à développer.

Chargement dynamique d’une DLL

En DotNet, pour charger dynamiquement une DLL, il faut utiliser les fonctions Assembly présente dans System.Reflection. Voici le code le plus simple possible qui vous permettra de charger dynamiquement une DLL en lui passant en paramètre son emplacement:

Private Sub LoadDll(ByVal dllPath As String)
    Try
        PtrPlugin = Nothing
        Dim ass As String = Path.GetFullPath(dllPath)
        Dim ptrAssembly As Assembly = Assembly.LoadFile(ass)
 
        For Each itm As Type In ptrAssembly.GetTypes
            If itm.IsClass Then
                If itm.GetInterfaces().Contains(GetType(IPlugin)) Then
                    PtrPlugin = CType(Activator.CreateInstance(itm), IPlugin)
                End If
            End If
        Next
        If PtrPlugin Is Nothing Then
            Throw New Exception("Invalid DLL, Interface not found")
        Else
            Debug.WriteLine("[OK] Dll loaded")
        End If
 
    Catch ex As Exception
        Debug.WriteLine("[ERROR] " & ex.Message & vbCrLf & ex.StackTrace)
    End Try
End Sub

Vous noterez juste que la création de l’instance issue de votre plugin se fera grâce à la classe Activator.

Exécuter le code du plugin

Maintenant que notre plugin est correctement chargé, on va pouvoir exécuter les fonctions qu’il implémente:

Private Sub BtExecute_Click(sender As Object, e As EventArgs) Handles BtExecute.Click
	If PtrPlugin IsNot Nothing Then
		MsgBox(PtrPlugin.Hello)
	End If
End Sub

L’utilisation d’un système de plugins dans une application DotNet n’est donc pas compliquée à mettre en place. Je mets à votre disposition le code source de mon projet de gestion de plugins.

Leave a Reply

Your email address will not be published. Required fields are marked *