CreateInstance () - Estou fazendo esse direito?
-
09-09-2019 - |
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.
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).