Compartilhar via


Redirecionar versões de assembly

Nota

Este artigo é específico do .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.

Você pode redirecionar referências de associação de tempo de compilação para assemblies do .NET Framework, assemblies de terceiros ou assemblies do seu próprio aplicativo. Você pode redirecionar seu aplicativo para usar uma versão diferente de um assembly de várias maneiras: por meio da política do editor, por meio de um arquivo de configuração de aplicativo ou por meio do arquivo de configuração do computador. Este artigo discute como a associação de assembly funciona no .NET Framework e como você pode configurá-la.

Dica

Este artigo é específico para aplicativos do .NET Framework. Para informações sobre o carregamento de assembly no .NET 5+ (e no .NET Core), confira Carregamento de dependência no .NET.

Unificação de assembly e associação padrão

As associações para assemblies do .NET Framework às vezes são redirecionadas por meio de um processo chamado unificação de assembly. O .NET Framework consiste em uma versão do common language runtime e cerca de duas dúzias de assemblies do .NET Framework que compõem a biblioteca de tipos. Esses assemblies do .NET Framework são tratados pelo runtime como uma única unidade. Por padrão, quando um aplicativo é iniciado, todas as referências a tipos no código executados pelo runtime são direcionadas para assemblies do .NET Framework que têm o mesmo número de versão que o runtime carregado em um processo. Os redirecionamentos que ocorrem com esse modelo são o comportamento padrão para o runtime.

Por exemplo, se o aplicativo fizer referência a tipos no namespace System.XML e tiver sido criado usando o .NET Framework 4.5, ele conterá referências estáticas ao assembly System.XML fornecido com o runtime versão 4.5. Se você quiser redirecionar a referência de associação para apontar para o assembly System.XML fornecido com o .NET Framework 4, você poderá colocar informações de redirecionamento no arquivo de configuração do aplicativo. Um redirecionamento de associação em um arquivo de configuração para um assembly do .NET Framework unificado cancela a unificação desse assembly.

Além disso, talvez você queira redirecionar manualmente a associação de assembly para assemblies de terceiros se houver várias versões disponíveis.

Dica

Se você atualizar um pacote NuGet que seu aplicativo referencia indiretamente e começar a ver novos erros como FileLoadException, MissingMethodException, TypeLoadExceptionou FileNotFoundException, talvez seja necessário habilitar redirecionamentos de associação automática ou adicionar manualmente um redirecionamento de associação. Isso é normal ao atualizar pacotes NuGet e é resultado de alguns pacotes sendo criados em relação a uma versão mais antiga de uma dependência. O seguinte trecho do arquivo de configuração do aplicativo adiciona um redirecionamento de associação para o pacote System.Memory:

<dependentAssembly>
   <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
   <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>

Redirecionar versões usando a política do editor

Os fornecedores de assemblies podem direcionar aplicativos para uma versão mais recente de um assembly, incluindo um arquivo de política de editor com o novo assembly. O arquivo de política do editor, que está localizado no cache de assembly global, contém configurações de redirecionamento de assembly.

Cada versão major.minor de um assembly tem o próprio arquivo de política de editor. Por exemplo, redirecionamentos da versão 2.0.2.222 para 2.0.3.000 e da versão 2.0.2.321 para a versão 2.0.3.000 entram no mesmo arquivo, pois estão associados à versão 2.0. No entanto, um redirecionamento da versão 3.0.0.999 para a versão 4.0.0.000 entra no arquivo para a versão 3.0.999. Cada versão principal do .NET Framework tem seu próprio arquivo de política de editor.

Se houver um arquivo de política de editor para um assembly, o runtime verificará esse arquivo depois de verificar o manifesto do assembly e o arquivo de configuração de aplicativos. Os fornecedores devem usar arquivos de política do editor somente quando o novo assembly for compatível com versões anteriores com o assembly que está sendo redirecionado.

Você pode ignorar a política do editor para seu aplicativo especificando as configurações no arquivo de configuração de aplicativos, conforme discutido na seção Ignorar política do editor.

Redirecionar versões no nível do aplicativo

Há algumas técnicas diferentes para alterar o comportamento de associação para seu aplicativo por meio do arquivo de configuração de aplicativos: você pode editar manualmente o arquivo, pode contar com o redirecionamento automático de associação ou pode especificar o comportamento de associação ignorando a política do editor.

Editar manualmente o arquivo de configuração do aplicativo

Você pode editar manualmente o arquivo de configuração do aplicativo para resolver problemas de assembly. Por exemplo, se um fornecedor lançar uma versão mais recente de um assembly que seu aplicativo usa sem fornecer uma política de publicação (porque não há garantia de compatibilidade com versões anteriores), você pode direcionar seu aplicativo para usar a versão mais recente do assembly definindo as informações de associação do assembly no arquivo de configuração do aplicativo da seguinte maneira.

<dependentAssembly>
  <assemblyIdentity name="someAssembly"
    publicKeyToken="32ab4ba45e0a69a1"
    culture="en-us" />
  <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>

Contar com o redirecionamento automático de associação

Quando você cria um aplicativo de área de trabalho no Visual Studio que tem como destino o .NET Framework 4.5.1 ou uma versão posterior, o aplicativo usa o redirecionamento automático de associação. Isso significa que, se dois componentes fizerem referência a versões diferentes do mesmo assembly de nome forte, o runtime adicionará automaticamente um redirecionamento de associação à versão mais recente do assembly no arquivo de configuração de aplicativos de saída (app.config). Esse redirecionamento substitui a unificação do assembly que, de outra forma, poderia ocorrer. O arquivo de app.config de origem não é modificado. Por exemplo, digamos que seu aplicativo referencie diretamente um componente do .NET Framework fora de banda, mas use uma biblioteca de terceiros direcionada a uma versão mais antiga do mesmo componente. Quando você compila o aplicativo, o arquivo de configuração do aplicativo de saída é modificado para conter um redirecionamento de associação para a versão mais recente do componente.

Se você criar um aplicativo web, receberá um aviso de build sobre o conflito de vinculação, que, por sua vez, oferece a opção de adicionar o redirecionamento de vinculação necessário ao arquivo de configuração web de origem.

Se você adicionar redirecionamentos de associação manualmente ao arquivo de app.config de origem, em tempo de compilação, o Visual Studio tentará unificar os assemblies com base nos redirecionamentos de associação adicionados. Por exemplo, digamos que você insira o seguinte redirecionamento de associação para um assembly:

<bindingRedirect oldVersion="3.0.0.0" newVersion="2.0.0.0" />

Se outro projeto em seu aplicativo fizer referência à versão 1.0.0.0 do mesmo assembly, o redirecionamento de associação automática adicionará a seguinte entrada ao arquivo de saída app.config para que o aplicativo seja unificado na versão 2.0.0.0 deste assembly:

<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />

Você pode habilitar o redirecionamento automático de associação se o aplicativo for direcionado a versões mais antigas do .NET Framework. Você pode substituir esse comportamento padrão fornecendo informações de redirecionamento de associação no arquivo app.config para qualquer assembly ou desativando o recurso de redirecionamento de associação. Para obter informações sobre como ativar ou desativar esse recurso, confira Como habilitar e desabilitar o redirecionamento automático de associação.

Ignorar a política do editor

Você pode substituir a política do editor no arquivo de configuração de aplicativos, se necessário. Por exemplo, novas versões de assemblies que afirmam ser compatíveis com versões anteriores ainda podem interromper um aplicativo. Se você quiser ignorar a política do editor, adicione um elemento <publisherPolicy> ao elemento <dependentAssembly> no arquivo de configuração do aplicativo e defina o atributo apply como no, que substitui as configurações de yes anteriores.

<publisherPolicy apply="no" />

Ignore a política do editor para manter seu aplicativo em execução para seus usuários, mas não deixe de relatar o problema ao fornecedor do assembly. Se um assembly tiver um arquivo de política de editor, o fornecedor deverá verificar se o assembly é compatível com versões anteriores e se os clientes podem usar a nova versão o máximo possível.

Redirecionar versões para testes, plug-ins ou bibliotecas usadas por outro componente

Para testes, você deve gerar um arquivo .dll.config. A maioria das estruturas de teste de unidade existentes respeita esses arquivos ao carregar testes.

Os plug-ins podem honrar arquivos .dll.config, porém, também podem não conseguir. O único mecanismo à prova de falhas para redirecionamentos é fornecendo bindingRedirects quando o AppDomain é criado.

Você pode tentar resolver esse problema com manipuladores de eventos AssemblyResolve, mas isso não funciona, pois esses manipuladores são chamados apenas em uma carga com falha. Se uma carga de assembly for bem-sucedida, seja porque foi carregada por outro assembly, pelo host, ou estava presente no GAC, um manipulador de AssemblyResolve não será chamado.

Redirecionar versões no nível do computador

Pode haver casos raros em que um administrador de computador deseja que todos os aplicativos em um computador usem uma versão específica de um assembly. Por exemplo, uma versão específica pode corrigir uma falha de segurança. Se um assembly for redirecionado no arquivo de configuração do computador, chamado machine.config, todos os aplicativos nesse computador que usam a versão antiga serão direcionados para usar a nova versão. O arquivo de configuração do computador substitui o arquivo de configuração do aplicativo e o arquivo de política do editor. Esse arquivo machine.config está localizado em %windir%\Microsoft.NET\Framework[version]\config\machine.config para computadores de 32 bits ou %windir%\Microsoft.NET\Framework64[version]\config\machine.config para computadores de 64 bits.

Especificar associação de assembly em arquivos de configuração

Use o mesmo formato XML para especificar redirecionamentos de associação, seja no arquivo de configuração do aplicativo, no arquivo de configuração do computador ou no arquivo de política do editor. Para redirecionar uma versão de assembly para outra, use o elemento bindingRedirect <>. O atributo oldVersion pode especificar uma única versão do assembly ou um intervalo de versões. O atributo newVersion deve especificar uma única versão. Por exemplo, <bindingRedirect oldVersion="1.1.0.0-1.2.0.0" newVersion="2.0.0.0"/> especifica que o runtime deve usar a versão 2.0.0.0 em vez das versões do assembly entre 1.1.0.0 e 1.2.0.0.

O exemplo de código a seguir demonstra uma variedade de cenários de redirecionamento de associação. O exemplo especifica um redirecionamento para um intervalo de versões para myAssemblye um único redirecionamento de associação para mySecondAssembly. O exemplo também especifica que o arquivo de política do editor não substituirá os redirecionamentos de associação para myThirdAssembly.

Para associar um assembly, você deve especificar a string "urn:schemas-microsoft-com:asm.v1" com o atributo xmlns na marcação assemblyBinding <>.

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="myAssembly"
          publicKeyToken="32ab4ba45e0a69a1"
          culture="en-us" />
        <!-- Assembly versions can be redirected in app,
          publisher policy, or machine configuration files. -->
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="mySecondAssembly"
          publicKeyToken="32ab4ba45e0a69a1"
          culture="en-us" />
             <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
      <assemblyIdentity name="myThirdAssembly"
        publicKeyToken="32ab4ba45e0a69a1"
        culture="en-us" />
        <!-- Publisher policy can be set only in the app
          configuration file. -->
        <publisherPolicy apply="no" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Limitar associações de assembly a uma versão específica

Você pode usar o atributo appliesTo no elemento <assemblyBinding> em um arquivo de configuração de aplicativo para redirecionar referências de associação de assembly para uma versão específica do .NET Framework. Esse atributo opcional usa um número de versão do .NET Framework para indicar a qual versão ele se aplica. Se nenhum atributo appliesTo for especificado, o elemento <assemblyBinding> se aplicará a todas as versões do .NET Framework.

Por exemplo, para redirecionar a associação de assembly para um assembly do .NET Framework 3.5, você incluiria o seguinte código XML no arquivo de configuração do seu aplicativo.

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
    appliesTo="v3.5">
    <dependentAssembly>
      <!-- assembly information goes here -->
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Insira informações de redirecionamento na ordem de versão. Por exemplo, insira informações de redirecionamento de associação de assembly para assemblies do .NET Framework 3.5 seguidos por assemblies do .NET Framework 4.5. Por fim, insira as informações de redirecionamento de associação de assembly para qualquer redirecionamento de assembly do .NET Framework que não use o atributo appliesTo e, portanto, que se aplique a todas as versões do .NET Framework. Se houver um conflito no redirecionamento, a primeira instrução de redirecionamento correspondente no arquivo de configuração será usada.

Por exemplo, para redirecionar uma referência a um assembly do .NET Framework 3.5 e outra referência a um assembly do .NET Framework 4, use o padrão mostrado no pseudocódigo a seguir.

<assemblyBinding xmlns="..." appliesTo="v3.5 ">
  <!--.NET Framework version 3.5 redirects here -->
</assemblyBinding>

<assemblyBinding xmlns="..." appliesTo="v4.0.30319">
  <!--.NET Framework version 4.0 redirects here -->
</assemblyBinding>

<assemblyBinding xmlns="...">
  <!-- redirects meant for all versions of the runtime -->
</assemblyBinding>

Consulte também