Pergunta

Eu estou tentando montar um sistema de plugins com .NET, e eu não tenho certeza se eu estou fazendo isso corretamente. A base do sistema é que um diretório específico ({apppath} / Plugins /) terá um monte de DLLs pré-compilados, e eu quero olhar através de cada um com a reflexão, e para cada classe disponível, se ele herda uma classe base específica (isto é definido em mais uma DLL, mas eu vou para isso mais tarde), em seguida, criar uma instância dele e chamar uma função específica na referida instância.

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

O problema específico que eu tenho é, eu não tenho certeza se este é o caminho certo para fazer isso. Será que o método que eu estou tentando fazer o trabalho, se pode-se supor que A.Plugin() realmente existe e todas as estruturas e classes referenciadas aqui estão livre de bugs? Se alguém precisar de mais código, a fim de ajuda, eu posso postá-lo.

Foi útil?

Solução

No geral a estratégia deve funcionar. A chamada assembly.LoadFrom vai carregar o alvo de montagem para o processo. De lá é possível fazer a inspeção tipo e criar instâncias desses tipos.

Eu acho que a maneira mais fácil e confiável para criar a instância é usar o método Activator.CreateInstance.

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

Dependendo de seus objetivos, outra sugestão seria para mover o bloco try / catch para o loop em vez de sair dela. Ter o bloco try / catch no exterior dos meios de circuito que se qualquer tipo de dado em uma faz a montagem tem um erro, você vai perder todos os tipos de que a montagem. Movê-lo dentro permitirá que você descartar apenas os tipos que não funcionam como expect.d O comportamento atual pode ser sua apesar intenção.

Outras dicas

Isso deve funcionar, eu tenho vindo a utilizar este tipo de coisa em alguns projetos antes. Eu especificamente olhou para um construtor e invocou mas para além de que era a mesma idéia.

Mas você pode querer olhar em MEF , que cuida de um monte de coisas para você para uma plugin de arquitetura (se você estiver disposto a esperar um pouco para a versão de lançamento, ainda é CTP por agora).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top