Domanda

Sto cercando di mettere insieme un sistema di plugin con .NET, e non sono sicuro se sto facendo in modo corretto. La base del sistema è che una directory specifica ({AppPath} / plugins /) avrà un sacco di DLL precompilati, e voglio guardare attraverso ognuna con la riflessione, e per ogni classe a disposizione, se si eredita una classe base specifica (questo è definito in un altro DLL, ma andrò in quella successiva), quindi creare un'istanza di esso e chiamare una funzione specifica in tale istanza.

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

Il problema specifico che ho è, io non sono sicuro che questo è il modo giusto per farlo. Sarebbe il metodo che sto cercando di fare il lavoro, se si può supporre che A.Plugin() esiste realmente ed eventuali strutture e classi si fa riferimento qui sono esenti da bug? Se qualcuno avrebbe bisogno di più il codice al fine di aiutare, posso postarlo.

È stato utile?

Soluzione

Nel complesso la strategia dovrebbe funzionare. La chiamata Assembly.LoadFrom caricherà il gruppo bersaglio nel processo. Da lì è possibile fare l'ispezione tipo e creare istanze di quei tipi.

Penso che il modo più semplice e affidabile per creare l'istanza è quello di utilizzare il metodo Activator.CreateInstance.

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

A seconda degli obiettivi, un altro suggerimento sarebbe quello di spostare il blocco try / catch nel circuito, invece di fuori di esso. Avendo il blocco try / catch all'esterno del ciclo significa che se un dato tipo in un assembly non ha un errore, si scarta tutti i tipi da tale assemblaggio. Muoversi dentro vi permetterà di scartare solo i tipi che non funzionano come expect.d Il comportamento attuale potrebbe essere il vostro intento però.

Altri suggerimenti

Questo dovrebbe funzionare, ho usato questo genere di cose in alcuni progetti prima. Ho guardato specificamente per un costruttore e invocato, ma a parte che era la stessa idea.

Ma si potrebbe desiderare di guardare MEF , che si prende cura di un sacco di cose per voi per una architettura a plugin (se siete disposti ad aspettare un po 'per la versione finale, è ancora CTP per ora).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top