Redirecionamento de associação de montagem: como e por quê?

126

Esta não é uma pergunta problemática, mas uma questão de entendimento geral sobre o trabalho do redirecionamento de ligação de assembly.

Consultas

  1. Por que o redirecionamento de ligação mostra apenas a versão principal e não os números menores, de compilação e revisão?
  2. As versões antiga e nova são alteradas apenas quando há alterações na versão principal?

    <dependentAssembly>
        <assemblyIdentity name="FooBar"  
                          publicKeyToken="32ab4ba45e0a69a1"  
                          culture="en-us" />  
    
        <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />  
    </dependentAssembly>
Nikhil Agrawal
fonte
Pode ser qualquer versão, não apenas a principal. Por exemplo:oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"
Evk
@ Evk: Todos os exemplos que eu vejo mostram apenas a versão principal.
Nikhil Agrawal
4
Bem, esses são apenas exemplos, e em nenhum lugar é declarado que é o único caminho possível.
EVK

Respostas:

165

Por que os redirecionamentos de ligação são necessários? Suponha que você tenha o aplicativo A que faça referência à biblioteca B e também à biblioteca C da versão 1.1.2.5. A biblioteca B, por sua vez, também faz referência à biblioteca C, mas da versão 1.1.1.0. Agora temos um conflito, porque você não pode carregar versões diferentes do mesmo assembly em tempo de execução. Para resolver esse conflito, você pode usar o redirecionamento de ligação, geralmente para a nova versão (mas também pode ser para a antiga). Você faz isso adicionando o seguinte ao arquivo app.config do aplicativo A, na configuration > runtime > assemblyBindingseção (veja aqui um exemplo de arquivo de configuração completo):

<dependentAssembly>
    <assemblyIdentity name="C"  
                      publicKeyToken="32ab4ba45e0a69a1"  
                      culture="en-us" />  

    <bindingRedirect oldVersion="1.1.1.0" newVersion="1.1.2.5" />  
</dependentAssembly>

Você também pode especificar um intervalo de versões para mapear:

<bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.2.5" />  

Agora a biblioteca B, que foi compilada com referência ao C da versão 1.1.1.0, usará o C da versão 1.1.2.5 no tempo de execução. Obviamente, é melhor garantir que a biblioteca C seja compatível com versões anteriores ou isso possa levar a resultados inesperados.

Você pode redirecionar qualquer versão das bibliotecas, não apenas as principais.

Evk
fonte
Em qual arquivo e em qual seção eles entram? Alguém pode fornecer um link para fonte como MSDN ou similar para referência? Lembre-se de que as pessoas estarão acessando seus artigos de SO Q / A de toda a esfera do mecanismo de pesquisa e as referências são críticas. Eu pedi a um colega de trabalho que me dissesse "basta adicionar um redirecionamento de montagem ao seu arquivo exe" antes de sair de férias por uma semana e eu cheguei aqui e, embora essa resposta pareça ótima, falta contexto e referência.
tpartee
Perguntas válidas @partee, editei a resposta (aguardando revisão por pares) para incluir a seção de configuração e um link para docs.microsoft.com/en-us/dotnet/framework/configure-apps/…
Kobus Smit
1
@AlexanderDerck no arquivo de configuração do aplicativo A - eles não têm efeito (tanto quanto sei) nos arquivos de configuração das bibliotecas, exceto talvez quando essa biblioteca é uma biblioteca de teste de unidade e é "executada" em algum sentido pelo executor de teste de unidade.
Evk
1
@AlexanderDerck, havia uma pergunta algumas semanas atrás, com muitos votos positivos e até recompensas, que perguntavam exatamente isso, mas ninguém foi capaz de fornecer uma resposta convincente - stackoverflow.com/q/48377474/5311735
Evk
1
@CodeEngine publicKeyToken identifica o assembly C. Somente os assemblies assinados têm esse token de chave pública para identificá-los. Aqui está uma pergunta relacionada sobre como você pode descobrir esse token, pois possui montagem: stackoverflow.com/q/3045033/5311735
Evk
55

Encontramos um problema com o redirecionamento de ligação para o NewtonSoft.Json. Procuramos a versão do arquivo nas propriedades do arquivo win 10 "9.0.1.19813", procuramos o número e o redirecionamento continuava falhando. Investigações adicionais e descobrimos que estávamos analisando a versão do arquivo e não a versão do assembly. Então, eu me pergunto se as pessoas estão enganando a versão do arquivo (que muda frequentemente) e a versão do assembly (que você não pode ver no Windows 10 File Explorer). Para ver a versão Assembly de uma dll, você pode executá-la no PowerShell. Substitua o nome da dll pelo nome para o qual deseja encontrar a versão.

[Reflection.AssemblyName]::GetAssemblyName('C:\development\bin\Newtonsoft.Json.dll').Version

O resultado acima é.

Major  Minor  Build  Revision

-----  -----  -----  --------

9      0      0      0

Veja referências:

Como posso ver a versão do assembly .NET do Windows Vista e mais recente (Windows 7, 2008)?

https://support.microsoft.com/en-nz/help/556041

insira a descrição da imagem aqui

Um mito
fonte
12
Promovido por trazer a diferença entre a versão do arquivo e a versão do assembly !!
mrid