Pregunta

Estoy tratando de armar un sistema de plugins con .NET, y no estoy seguro de si lo estoy haciendo correctamente. La base del sistema es que un directorio específico ({AppPath} / plugins /) tendrá un montón de DLL precompilados, y quiero mirar a través de cada uno de ellos con la reflexión, y para todas las clases disponibles, si se hereda de una clase base específica (esto se define en otro archivo DLL, pero voy a entrar en eso más adelante), a continuación, crear una instancia de ella y llamar a una función específica en dicha instancia.

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

El problema que tengo es específica, no estoy seguro de que esta es la forma correcta de hacer esto. ¿El método que yo estoy tratando de hacer el trabajo, si se puede suponer que existe realmente A.Plugin() y cualquier estructura y clases que se hace referencia aquí son libres de errores? Si alguien necesita más código con el fin de ayudar, puedo publicarlo.

¿Fue útil?

Solución

En general, la estrategia debería funcionar. La llamada Assembly.LoadFrom se carga el ensamblaje de destino en el proceso. Desde allí es posible hacer la inspección tipo y crear instancias de estos tipos.

Creo que la forma más fácil y fiable para crear la instancia es utilizar el método Activator.CreateInstance.

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

En función de sus objetivos, otra sugerencia sería mover el bloque try / catch en el bucle en lugar de salir de ella. Tener el bloque Try / Catch en el exterior del bucle significa que si cualquier tipo dado en una asamblea tiene un error, se le descartar todos los tipos de ese montaje. Moverlo dentro le permitirá descartar sólo los tipos que no funcionan como expect.d El comportamiento actual puede ser su intención sin embargo.

Otros consejos

Esto debería funcionar, he estado utilizando este tipo de cosas en algunos proyectos antes. Miré específicamente para un constructor e invocados, pero aparte de eso, era la misma idea.

Sin embargo, es posible que desee mirar a MEF , que se ocupa de un montón de cosas para usted para una arquitectura de plugins (si usted está dispuesto a esperar un poco para la versión de lanzamiento, sigue siendo CTP por ahora).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top