Question

Je suis en train de mettre en place un système de plug-ins avec .NET, et je ne sais pas si je le fais correctement. La base du système est qu'un répertoire spécifique ({AppPath} / Plugins /) aura un tas de DLL précompilés, et je veux regarder à travers chacun avec la réflexion, et pour toutes les classes disponibles, si elle hérite d'une classe de base spécifique (ce qui est défini dans une autre DLL, mais je vais aller dans plus tard), puis créer une instance de celui-ci et appeler une fonction spécifique dans ladite instance.

Public Sub ScanPluginsInDirectory(ByVal Directory As String)

    Dim Plugins As New IO.DirectoryInfo(Directory)
    Dim Files As IO.FileInfo() = Plugins.GetFiles("*.dll")
    Dim CryptType As Type = GetType(CryptPluginBase)
    Dim PluginsData as List(Of LoadedPluginsInfo)

    For Each DllFile As IO.FileInfo In Files
        Try
            Dim thisAsm As Assembly = Assembly.LoadFrom(DllFile.FullName)
            Dim ClassDefs = thisAsm.GetTypes().Where(Function(type) CryptType.IsAssignableFrom(type))

            For Each ClassDef As Type In ClassDefs
                Dim A As Object
                A = ClassDef.Assembly.CreateInstance(ClassDef.Name)
                PluginsData.Add(New LoadedPluginsInfo(A.Plugin(), False))
            Next
        Catch ex As Exception
            Continue For
        End Try
    Next
End Sub

Le problème spécifique que j'ai est, je ne suis pas sûr que ce soit la bonne façon de le faire. Est-ce que la méthode que je suis en train de faire le travail, si l'on peut supposer que A.Plugin() existe et toutes les structures et les classes référencées ici sont sans bug? Si quelqu'un aurait besoin de plus de code afin d'aider, je peux l'afficher.

Était-ce utile?

La solution

Dans l'ensemble de la stratégie devrait fonctionner. L'appel Assembly.LoadFrom chargera l'ensemble cible dans le processus. De là, il est possible de faire une inspection de type et de créer des instances de ces types.

Je pense que la façon de créer l'instance la plus simple et la plus fiable est d'utiliser la méthode de Activator.CreateInstance.

For Each def As Type in ClassDefs
  Dim inst = Activator.CreateInstance(def)
  PluginsData.Add(new LoadedPluginsInfo(inst.Plugin(), False))
Next

En fonction de vos objectifs, une autre suggestion serait de déplacer le bloc try / catch dans la boucle au lieu de sortir. Avoir le Try / Catch bloc à l'extérieur de la boucle signifie que si un type donné dans un ensemble ne une erreur, vous jetez tous les types de cette assemblée. Se déplacer à l'intérieur vous permettra de refuser que les types qui ne fonctionnent pas comme expect.d Le comportement actuel peut être votre intention bien.

Autres conseils

Cela devrait fonctionner, je me sers de ce genre de chose dans certains projets avant. J'ai regardé spécifiquement pour un constructeur et a invoqué, mais à part ça c'était la même idée.

Mais vous voudrez peut-être regarder MEF, qui prend soin de beaucoup de choses pour vous pour un l'architecture plugin (si vous êtes prêt à attendre un peu pour la version, il est encore CTP pour l'instant).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top