2009-04-12 6 views
4

J'essaie de mettre en place un système de plugins avec .NET, et je ne suis pas sûr 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ées, et je veux parcourir chacune d'entre elles avec la réflexion, et pour chaque classe disponible, si elle hérite d'une classe de base spécifique (ceci est défini dans une autre DLL, mais j'y reviendrai plus tard), puis en crée une instance et appelle une fonction spécifique dans cette instance.Createinstance() - Est-ce que je fais ça correctement?

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, c'est que je ne suis pas sûr que ce soit la bonne façon de procéder. Est-ce que la méthode que j'essaye de faire fonctionner, si on peut supposer que A.Plugin() existe réellement et toutes les structures et classes référencées ici sont sans bug? Si quelqu'un a besoin de plus de code pour aider, je peux le poster.

Répondre

3

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

Je pense que la méthode la plus simple et la plus fiable pour créer l'instance consiste à utiliser la méthode Activator.CreateInstance. En fonction de vos objectifs, une autre suggestion consisterait à déplacer le bloc Try/Catch dans la boucle au lieu d'en sortir. Avoir le bloc Try/Catch à l'extérieur de la boucle signifie que si un type donné dans un assembly a une erreur, vous supprimerez tous les types de cet assembly. Le déplacer à l'intérieur vous permettra de ne jeter que les types qui ne fonctionnent pas comme expect.d Le comportement actuel peut être votre intention cependant.

+0

Voulez-vous dire inst.Plugin()? – Sukasa

+0

@Sukasa, oui. Je l'ai corrigé. – JaredPar

+1

D'accord, je n'étais pas sûr s'il y avait un petit tour dont je n'étais pas au courant. Merci! – Sukasa

1

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

Mais vous voudrez peut-être regarder MEF, qui s'occupe BEAUCOUP de choses pour vous pour une architecture de plugin (si vous êtes prêt à attendre un peu pour la version, c'est toujours CTP pour l'instant).