Diferença entre LoadFile e LoadFrom com assemblies .NET?
Eu estava olhando a documentação do msdn e ainda estou um pouco confuso sobre qual é exatamente a diferença entre usar LoadFilee LoadFromcarregar um assembly. Alguém pode fornecer um exemplo ou uma analogia para melhor descrevê-lo. A documentação do MSDN me confundiu mais. Além disso, é ReflectionOnlyLoadFromo mesmo que LoadFromexceto que ele carrega a montagem apenas no modo de reflexão.
Como minha experiência em .NET não é a melhor, aqui estão algumas perguntas sobre a documentação do MSDN usando o LoadFile:
1) O que significa LoadFileexaminar assembléias com a mesma identidade, mas localizadas em caminhos diferentes? Qual é a identidade (exemplo)?
2) Ele afirma LoadFileque não carrega arquivos no 'Contexto LoadFrom' e não resolve dependências usando o caminho de carregamento. O que isso significa, alguém pode dar um exemplo?
3) Por fim, afirma que LoadFileé útil nesse cenário limitado porque o LoadFrom não pode carregar assemblies que tenham as mesmas identidades, mas caminhos diferentes; ele carregará apenas o primeiro assembly, o que novamente me leva à mesma pergunta: qual é a identidade dos assemblies?
.net assemblies system.reflection assembly-loading
Seriamente eu também acho que às vezes que MS deve contratar melhores escritores ou qualquer outra coisa desde que as frases nem sempre são compreensíveis ...
Veja também não- documentação
@ColonelPanic MS pode dizer que tudo está documentado ... mas com um fator de ajuda de zeroooo.
Isso esclarece?
assembly2 = Assembly.LoadFile(path2);
// These point to different assemblies now, so this is false
Editar : para responder às perguntas que você levantou na sua pergunta revisada, você definitivamente quer ler Suzanne Cook sobre Assembly Identity .
Existem muitas regras que governam como os assemblies são carregados e alguns deles têm a ver com a maneira como resolvem dependências - se o AssemblyA é dependente do AssemblyB, onde o .NET deve procurar o AssemblyB? No Global Assembly Cache, o mesmo diretório que encontrou AssemblyA, ou em algum outro lugar inteiramente? Além disso, se encontrar várias cópias dessa montagem, como escolher qual usar?
LoadFromtem um conjunto de regras, enquanto LoadFiletem outro conjunto de regras. É difícil imaginar muitas razões para usar LoadFile, mas se você precisar usar a reflexão em diferentes cópias da mesma montagem, está lá para você.
— Jeff Sternal
O CodeBase é o mesmo que a identidade?
Não, eu apenas usei o CodeBase aqui como uma propriedade arbitrária do assembly para ilustrar que a segunda instância do Assembly estava apontando para o arquivo 'errado' (no primeiro exemplo). Estou atualizando minha resposta com mais detalhes.
Isso esclarece um pouco, mas como o path1 e o path2 apontam para cópias diferentes do mesmo assembly no disco ao usar o LoadFrom e ao usar o LoadFile, o path1 e o path2 apontam para diferentes assemblies. Qual é um exemplo de qual caminho1 e caminho2 seria? Obrigado pela sua paciência.
— Xaisoft 25/09/2009
Por que você verifica duas referências de string para igualdade de valor string.Compare(x, y) == 0? Eu acho que você quer x == ylá? Se por motivos obscuros você deseja uma verificação de igualdade dependente da cultura, é mais claro escrever string.Equals(x, y, StringComparison.CurrentCulture), por exemplo.
@JeffSternal Fazer a ligação em "Suzanne Cozinhe em Assembleia Identidade" parece estar quebrado aqui ...
— Martin Verjans
Do blog de Suzanne Cook :
Tenha cuidado - estes não são a mesma coisa.
LoadFrom () passa pelo Fusion e pode ser redirecionado para outro assembly em um caminho diferente, mas com a mesma identidade se um já estiver carregado no contexto LoadFrom.
O LoadFile () não se liga ao Fusion - o carregador apenas avança e carrega exatamente * o que o chamador solicitou. Ele não usa o contexto Load ou LoadFrom.
Portanto, o LoadFrom () geralmente fornece o que você pediu, mas não necessariamente. LoadFile () é para quem realmente quer exatamente o que é solicitado. (* No entanto, a partir da v2, a política será aplicada a LoadFrom () e LoadFile (), portanto, LoadFile () não será necessariamente exatamente o que foi solicitado. Além disso, a partir da v2, se um assembly com sua identidade estiver em no GAC, a cópia do GAC será usada. Use ReflectionOnlyLoadFrom () para carregar exatamente o que você deseja - mas observe que os assemblies carregados dessa maneira não podem ser executados.
LoadFile () tem um problema. Como ele não usa um contexto de ligação, suas dependências não são encontradas automaticamente em seu diretório. Se eles não estiverem disponíveis no contexto Carregar, você precisará se inscrever no evento AssemblyResolve para vincular a eles.
Consulte também Escolhendo um artigo de contexto de ligação no mesmo blog.
Obrigado, vou verificar o blog, atualizei meu post com algumas perguntas sobre a documentação do msdn.
— Xaisoft 25/09/09
@Xaisoft - O blog de Suzanne Cook volta ao resgate com a resposta de uma identidade de assembléias. Consulte blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx . É essencialmente um "nome para exibição do assembly" e é algo como: "Sistema, Versão = 1.0.3300.0, Culture = neutral, PublicKeyToken = b77a5c561934e089", portanto, inclui o nome real do assembly, o número da versão e outras informações de identificação (como PublicKeyToken etc.).
A que ela está se referindo quando fala sobre o Fusion?
Na verdade, Jeff está no local. Veja este link: grimes.demon.co.uk/workshops/fusionWS.htm para obter um bom tutorial sobre o subsistema Fusion e sua tecnologia para carregar assemblies no .NET
Apenas uma atualização rápida, observe que o URL acima (grimes.demon.co.uk/workshops/fusionWS.htm) não é mais válido e agora foi movido para: richardgrimes.com/workshops/fusionWS.htm
Depois de muito coçar a cabeça, descobri uma diferença esta tarde.
Eu queria carregar uma DLL em tempo de execução, e a DLL residia em outro diretório. Essa DLL tinha suas próprias dependências (DLLs), que também residiam no mesmo diretório.
LoadFile (): carregou a DLL específica, mas não as dependências. Portanto, quando a primeira chamada foi feita de dentro da DLL para uma dessas outras DLLs, lançou um FileNotFoundException.
LoadFrom (): carregou a DLL que especifiquei e também todas as dependências que viviam nesse diretório.
— LordWilmore
Esse foi exatamente o meu problema! Eu estava recebendo a FileNotFoundExceptionmensagem ao criar uma nova instância de um objeto definido em um assembly referenciado pelo assembly que eu acabei de carregar .LoadFile. Alterar isso para .LoadFromapareceu para corrigir o problema, mas eu não sabia o porquê! Obrigado
Obrigado, eu estava tendo o mesmo problema.
— Ivandro IG Jao 25/11
Nota: Se um assembly for carregado usando um caminho 8.3 e, a partir de um caminho não-8.3, eles serão vistos como conjuntos diferentes, mesmo que sejam a mesma DLL física.
— Gregg DeMasters
O .NET possui um contexto de carregamento diferente. Suzanne Cook escreveu sobre eles aqui: http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx
É assim que as .Net colocam as referências em quarentena.
uma diferença que eu notei é:
Assembly.LoadFile - Carrega o assembly no AppDomain diferente, com direitos de usuário limitados (princípio da diferença). operações como serilização / desserilização não puderam ser executadas.
Assembly.LoadFrom - Carrega o assembly no mesmo AppDomain com os mesmos direitos de usuário (mesmo princípio).
Isso não está correto. O que faz você acreditar que Assembly.LoadFile carrega um assembly em outro AppDomain?
— fr34kyn01535
No meu caso, eu apenas tive que excluir o cache do aplicativo ASP localizado @ C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files. É reconstruído quando o site é executado pela primeira vez. Certifique-se de parar o IIS primeiro.