Reflection.Net: como carregar dependências?
-
05-07-2019 - |
Pergunta
Eu tento adicionar um sistema de complementos ao meu pedido Windows.Net usando reflexão; mas falha quando há addon com dependencie.
classe addon tem que implementar uma interface 'IAddon' e ter um construtor vazio.
carga programa principal do complemento usando Reflexão:
Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\Addon.dll");
Type t = assembly.GetType("Test.MyAddon");
ConstructorInfo ctor = t.GetConstructor(new Type[] { });
IAddon addon= (IAddon) ctor.Invoke(new object[] { });
addon.StartAddon();
Ele funciona muito bem quando addon não use dependencie.
Mas se minha referência addon e usar um outro DLL (C: \ Temp \ TestAddon \ MyTools.dll) que é guardado perto do addon em disco, ele falhar:
System.IO.FileNotFoundException:. Não foi possível carregar arquivo ou assembly 'MyTools.dll' ou uma de suas dependências
Eu não quer copiar os complementos DLL perto da minha executável, como posso fazer para contar .NET Runtime para procurar em "C: \ Temp \ TestAddon \"? Para qualquer dependência
Note que a adição
Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\MyTools.dll");
não muda nada.
Solução
Se MyTools.dll está localizado no mesmo diretório como Addon.dll , tudo que você precisa fazer é chamar Assembly.LoadFrom
vez de Assembly.LoadFile
para fazer o seu trabalho de código. Caso contrário, manipulando o evento AppDomain.AssemblyResolve
é o caminho a percorrer.
Outras dicas
Você olhou para usando um inversão de controle recipiente? Eu uso o Castelo de Windsor com um arquivo Boo externa que me permite facilmente estender o applcation sem ter que recompilar ou se preocupar com o fornecimento de dependências
Você pode usar o reflexo para o acesso privado Assembly.
_GetReferencedAssemblies()
.
Embora, o método pode mudança em uma versão futura do framework .NET, não parece likely-ASP.NET fortemente depende dele, mas é possível que eles possam movê-lo de mscorlib
para System.Web
que é a única assembleia que eu saiba de onde o método é referido.
Assembly.LoadFrom funciona bem até eu tentar usar um webservice no meu addon, eu tinha tido um " Não é possível para objeto fundido do tipo 'X' para digitar 'X' " exceção.
É feio, mas vou usar Assembly.LoadFile com o AppDomain.AssemblyResolve.
Obrigado rapazes.
par de opções:
- Você pode anexar a
AppDomain.AssemblyResolve
para ajudar a resolver CLR do conjunto. - Você pode olhar para isolar add-ins em seu próprio
AppDomain
(vejaSystem.AddIn
namespace e este site ).