Como carregar a assembly em tempo de execução antes do evento AssemblyResolve? DoCow
.net 3.5 assemblies c #
Como carregar a assembly em tempo de execução antes do evento AssemblyResolve?
Na verdade eu tentei implementar algum tipo de assembléias 'estaticamente ligadas', dentro da minha solução. Então eu tentei o seguinte:
Adicionando uma referência ao meu assembly com CopyLocal = false
Adicionando o próprio arquivo .dll à minha solução com 'Adicionar como link'
Adicionando o próprio arquivo .dll aos meus resources com 'Add Resource' – 'Add Existing File'
Adicionando algum tipo fora do meu assembly no Form1 como private MyObject temp = new MyObject();
Após essas etapas eu tenho o FileNotFoundException conforme o esperado. Então, vamos tentar carregar o assembly dentro do AssemblyResolveEvent com este hack rápido
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => { Assembly MyAssembly = AppDomain.CurrentDomain.Load(Properties.Resources.ExternalAssembly); return MyAssembly; };
Então isso funciona! Eu sou capaz de carregar meu assembly de um arquivo de recurso dentro de um AssemblyResolveEvent. Mas esse evento só acontece se não conseguir encontrar minha assembly em outro lugar. Mas como posso obter o meu assembly ser carregado antes. Net tenta pesquisar os diferentes lugares?
Devido aos fatos da verificação de conjuntos referenciados anteriormente, eu pensei que seria possível carregar o assembly antes no domínio e isso seria feito.
Um método para contar ocorrências em uma lista
Eu tentei isso dentro program.cs usando o seguinte método Main ()
static void Main() { LoadMyAssemblies(); AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => LoadMyAssemblies(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } private static Assembly LoadMyAssemblies() { Assembly result = AppDomain.CurrentDomain.Load(Properties.Resources.MyStaticAssembly); return result; }
Mas ainda corre para o ResolveEventHandler. E muito mais melhor, se eu carregar o assembly novamente e dar uma olhada no AppDomain.CurrentDomain.GetAssemblies () eu posso ver que meu assembly é carregado duas vezes !!
Então, alguma idéia por que o meu assembly carregado não será levado em consideração quando é carregado antes do evento AssemblyResolve? Com a ajuda do depurador, também retornei um nulo quando a chamada veio do AssemblyResolve, mas, neste caso, recebi uma FileNotFoundException como no início.
Apenas no caso de você não saber, existe uma ferramenta chamada ILMerge da MS Research que mescla assemblies em um arquivo.
Além disso, você pode criar montagens de vários arquivos usando a ferramenta Assembly Linker .
Além disso, para responder a sua pergunta original, o problema é que o tempo de execução não sabe que o assembly que você carregou manualmente é o que ele deve procurar. Portanto, no assembly resolve o evento em vez de carregar o assembly novamente, apenas retorne a referência para o assembly que você carregou manualmente.
O CLR Binder não sabe que LoadMyAssemblies () faz a mesma coisa que o evento AssemblyResolve e que ambos estão tentando procurar o mesmo assembly e carregá-lo.
O evento AssemblyResolve sempre é acionado no ponto em que o Binder decide que pesquisou todos os locais possíveis (que podem ser pesquisados ​​por esse aplicativo) e não conseguiu encontrar uma correspondência.
Isso implora a pergunta original, que é, por que você deseja vincular estaticamente seus assemblies gerenciados? Leia este tópico para muita discussão sobre estas vantagens de binding estática
Vou em frente e respondo a parte sobre como evitar o evento AssemblyResolve 1) Coloque o assembly no GAC. No que diz respeito ao Binder, o GAC sempre vence. 2) Coloque seu assembly no caminho de investigação e certifique-se de que o Binder o pegue (procure o artigo 'Como o tempo de execução localiza assemblies' no MSDN para saber mais sobre isso).