Freigeben über


Umleiten von Assemblyversionen

Hinweis

Dieser Artikel ist spezifisch für .NET Framework. Sie gilt nicht für neuere Implementierungen von .NET, einschließlich .NET 6 und höherer Versionen.

Sie können Verweise zur Kompilierungszeitbindung auf .NET Frameworkassemblys, Assemblys von Drittanbietern oder die Assemblys Ihrer eigenen App umleiten. Sie können Ihre App auf verschiedene Arten umleiten, um eine andere Version einer Assembly zu verwenden: über die Herausgeberrichtlinie, über eine App-Konfigurationsdatei oder über die Computerkonfigurationsdatei. In diesem Artikel wird erläutert, wie die Assemblybindung in .NET Framework funktioniert und wie Sie sie konfigurieren können.

Tipp

Dieser Artikel ist spezifisch für .NET Framework-Apps. Informationen zum Laden von Assemblys in .NET 5+ (und .NET Core) finden Sie unter Dependency loading in .NET.

Assemblyvereinheitlichung und Standardbindung

Bindungen an .NET Framework-Assemblys werden manchmal über einen Prozess namens assembly unification umgeleitet. .NET Framework besteht aus einer Version der Common Language Runtime und etwa zwei Dutzend .NET Framework-Assemblys, aus denen die Typbibliothek besteht. Diese .NET Framework-Assemblys werden von der Laufzeit als einzelne Einheit behandelt. Wenn eine App gestartet wird, werden standardmäßig alle Verweise auf Typen in Code, die von der Laufzeit ausgeführt werden, an .NET Framework-Assemblys weitergeleitet, die dieselbe Versionsnummer wie die Laufzeit aufweisen, die in einem Prozess geladen wird. Die Umleitungen, die mit diesem Modell auftreten, sind das Standardverhalten für die Laufzeit.

Wenn Ihre App beispielsweise auf Typen im System.XML-Namespace verweist und mithilfe von .NET Framework 4.5 erstellt wurde, enthält sie statische Verweise auf die System.XML-Assembly, die mit Laufzeitversion 4.5 ausgeliefert wird. Wenn Sie den Bindungsverweis so umleiten möchten, dass er auf die System.XML Assembly verweist, die mit .NET Framework 4 ausgeliefert wird, können Sie Umleitungsinformationen in die App-Konfigurationsdatei einfügen. Eine Bindungsumleitung in einer Konfigurationsdatei für eine einheitliche .NET Framework-Assembly bricht die Vereinheitlichung für diese Assembly ab.

Darüber hinaus möchten Sie möglicherweise die Assembly-Bindung für Assemblys von Drittanbietern manuell umleiten, wenn mehrere Versionen verfügbar sind.

Tipp

Wenn Sie ein NuGet-Paket aktualisieren, auf das Ihre Anwendung indirekt verweist und neue Fehler wie FileLoadException, MissingMethodException, TypeLoadException oder FileNotFoundException sehen, müssen Sie möglicherweise automatische Bindungsumleitungen aktivieren oder manuell eine Bindungsumleitung hinzufügen. Dies ist normal beim Aktualisieren von NuGet-Paketen und das Ergebnis einiger Pakete, die mit einer älteren Version einer Abhängigkeit erstellt werden. Der folgende App-Konfigurationsdateiauszug fügt eine Bindungsumleitung für das System.Memory-Paket hinzu:

<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>

Umleiten von Versionen mithilfe der Herausgeberrichtlinie

Lieferanten von Assemblys können Anwendungen auf eine neuere Version einer Assembly umleiten, indem sie eine Richtliniendatei des Herausgebers mit der neuen Assembly einschließen. Die Herausgeberrichtliniendatei befindet sich im globalen Assemblycache und enthält Einstellungen für die Umleitung der Assembly.

Jede Version einer Assembly im Format major.minor verfügt über eine eigene Herausgeberrichtliniendatei. Umleitungen von Version 2.0.2.222 zu 2.0.3.000 und von Version 2.0.2.321 zu Version 2.0.3.000 gehen beide in dieselbe Datei, da sie version 2.0 zugeordnet sind. Eine Umleitung von Version 3.0.0.999 zu 4.0.0.000 müsste jedoch in der Datei für die Version 3.0.999 stehen. Jede Hauptversion des .NET Framework verfügt über eine eigene Herausgeberrichtliniendatei.

Wenn eine Herausgeberrichtliniendatei für eine Assembly vorhanden ist, überprüft die Laufzeit diese Datei nach der Überprüfung der Manifest- und App-Konfigurationsdatei der Assembly. Anbieter sollten Publisher-Richtliniendateien nur verwenden, wenn die neue Assembly abwärtskompatibel mit der umgeleiteten Assembly ist.

Sie können die Herausgeberrichtlinie für Ihre App umgehen, indem Sie Einstellungen in der App-Konfigurationsdatei angeben, wie im Abschnitt " Herausgeberrichtlinie umgehen " beschrieben.

Umleiten von Versionen auf App-Ebene

Es gibt ein paar verschiedene Techniken zum Ändern des Bindungsverhaltens für Ihre App über die App-Konfigurationsdatei: Sie können die Datei manuell bearbeiten, sie können sich auf die automatische Bindungsumleitung verlassen, oder Sie können das Bindungsverhalten durch Umgehen der Herausgeberrichtlinie angeben.

Manuelles Bearbeiten der App-Konfigurationsdatei

Sie können die App-Konfigurationsdatei manuell bearbeiten, um Assemblyprobleme zu beheben. Wenn z. B. ein Hersteller eine neuere Version einer Assembly veröffentlicht, die Ihre App verwendet, ohne eine Herausgeberrichtlinie bereitzustellen (da sie keine Abwärtskompatibilität garantieren), können Sie Ihre App an die Verwendung der neueren Version der Assembly weiterleiten, indem Sie Assemblybindungsinformationen wie folgt in die Konfigurationsdatei Ihrer App einfügen.

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

Nutzen der automatische Bindungsumleitung

Wenn Sie eine Desktop-App in Visual Studio erstellen, die auf .NET Framework 4.5.1 oder höher ausgerichtet ist, verwendet die App die automatische Bindungsumleitung. Das bedeutet, dass, wenn zwei Komponenten auf unterschiedliche Versionen derselben stark benannten Assembly verweisen, die Laufzeit automatisch eine Bindungsumleitung zur neueren Version der Assembly in die Datei der Ausgabekonfiguration der App (app.config) einfügt. Diese Umleitung überschreibt die Assemblyvereinheitlichung, die sonst erfolgen würde. Die Quelle app.config Datei wird nicht geändert. Nehmen wir beispielsweise an, dass Ihre App direkt auf eine Out-of-Band-.NET Framework-Komponente verweist, aber eine Drittanbieterbibliothek verwendet, die auf eine ältere Version derselben Komponente ausgerichtet ist. Wenn Sie die App kompilieren, wird die Konfigurationsdatei der Ausgabe-App so geändert, dass sie eine Bindungsumleitung an die neuere Version der Komponente enthält.

Wenn Sie eine Web-App erstellen, erhalten Sie eine Buildwarnung bezüglich des Bindungskonflikts, wodurch Sie wiederum die Möglichkeit erhalten, der Quellwebkonfigurationsdatei die erforderliche Bindungsumleitung hinzuzufügen.

Wenn Sie Binding-Redirects manuell zur Quelldatei app.config hinzufügen, versucht Visual Studio, die Assemblys basierend auf den hinzugefügten Binding-Redirects zu vereinheitlichen. Wenn Sie zum Beispiel die folgende Bindungsumleitung für eine Assembly einfügen:

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

Wenn ein anderes Projekt in Ihrer App auf Version 1.0.0.0 derselben Assembly verweist, fügt die automatische Bindungsumleitung den folgenden Eintrag zur Ausgabedatei app.config Datei hinzu, sodass die App auf Version 2.0.0.0 dieser Assembly vereinheitlicht wird:

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

Sie können die automatische Bindungsumleitung aktivieren, wenn Ihre App auf ältere Versionen von .NET Framework ausgerichtet ist. Sie können dieses Standardverhalten außer Kraft setzen, indem Sie Bindungsumleitungsinformationen in der app.config-Datei für jede Assembly bereitstellen oder das Bindungsumleitungsfeature deaktivieren. Informationen zum Aktivieren oder Deaktivieren dieses Features finden Sie unter How to: Enable and Disable Automatic Binding Redirection.

Umgehen der Herausgeberrichtlinie

Sie können die Herausgeberrichtlinie bei Bedarf in der App-Konfigurationsdatei außer Kraft setzen. Beispielsweise können neue Versionen von Assemblys, die behaupten, abwärtskompatibel zu sein, dennoch eine App unterbrechen. Wenn Sie die Herausgeberrichtlinie umgehen möchten, fügen Sie dem <abhängigenAssembly-Element> in der App-Konfigurationsdatei ein <publisherPolicy-Element> hinzu und legen Sie das apply-Attribut auf no fest, um alle vorherigen yes Einstellungen außer Kraft zu setzen.

<publisherPolicy apply="no" />

Durch das Umgehen der Herausgeberrichtlinie bleibt Ihre App zwar lauffähig, doch sollten Sie dieses Problem auf jeden Fall dem Anbieter der Assembly mitteilen. Wenn eine Assembly über eine Herausgeberrichtliniendatei verfügt, sollte der Hersteller sicherstellen, dass die Assembly abwärtskompatibel ist und dass Clients die neue Version so weit wie möglich verwenden können.

Umleiten von Versionen für Tests, Plug-Ins oder Bibliotheken, die von einer anderen Komponente verwendet werden

Bei Tests sollten Sie eine .dll.config Datei generieren. Die meisten vorhandenen Komponententestframeworks berücksichtigen diese Dateien beim Laden von Tests.

Möglicherweise berücksichtigen Plugins .dll.config Dateien, aber möglicherweise nicht. Der einzige narrensichere Mechanismus für Umleitungen ist die Angabe von bindingRedirects bei der Erstellung von AppDomain.

Sie können versuchen, dieses Problem mit AssemblyResolve Ereignishandlern zu lösen, aber das funktioniert nicht, da diese Handler nur bei einem fehlgeschlagenen Laden aufgerufen werden. Wenn eine Assemblylade erfolgreich ist, entweder weil sie von einer anderen Assembly oder dem Host geladen wurde oder im GAC vorhanden war, wird kein AssemblyResolve Handler aufgerufen.

Generieren von Bindungsumleitungen für Komponententestprojekte

Komponententestprojekte werden in DLLs kompiliert, nicht ausführbare Dateien. Die automatische Bindungsumleitungsgenerierung gilt nur für ausführbare Ausgabetypen, sodass Komponententestprojekte standardmäßig keine Bindungsumleitungen empfangen. Wenn ein Komponententestprojekt auf Assemblys mit widersprüchlichen Versionen verweist, können Tests zur Laufzeit aufgrund von Ausnahmen wie z. B. FileLoadException fehlschlagen.

Um eine .dll.config-Datei mit Binding-Umleitungen für ein Unittestprojekt zu generieren, fügen Sie sowohl AutoGenerateBindingRedirects als auch GenerateBindingRedirectsOutputType dem Projektfile hinzu.

<PropertyGroup>
  <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
  <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

Die GenerateBindingRedirectsOutputType Eigenschaft weist MSBuild an, eine .dll.config Datei zusammen mit der Testassemblyausgabe zu generieren, obwohl der Ausgabetyp eine Klassenbibliothek (DLL) ist. Die meisten Testläufer, einschließlich VSTest, laden diese Konfigurationsdatei beim Ausführen von Tests.

Nachdem Sie diese Eigenschaften hinzugefügt und das Projekt neu erstellt haben, überprüfen Sie, ob neben der Testassembly eine .dll.config Datei im Buildausgabeverzeichnis angezeigt wird. Die Datei enthält die Bindungsumleitungen, die zum Beheben von Assemblyversionskonflikten zur Testlaufzeit erforderlich sind.

Umleiten von Versionen auf Computerebene

Es kann seltene Fälle geben, in denen ein Computeradministrator möchte, dass alle Apps auf einem Computer eine bestimmte Version einer Assembly verwenden. Beispielsweise kann eine bestimmte Version ein Sicherheitsloch beheben. Wenn eine Assembly in der Konfigurationsdatei des Computers (machine.config) umgeleitet wird, werden alle auf diesem Computer installierten Apps, die bisher die alte Version verwendet haben, zur neuen Version umgeleitet. Die Computerkonfigurationsdatei setzt die App-Konfigurationsdatei und die Herausgeberrichtliniendatei außer Kraft. Diese datei machine.config befindet sich unter %windir%\Microsoft.NET\Framework[version]\config\machine.config für 32-Bit-Computer oder %windir%\Microsoft.NET\Framework64[version]\config\machine.config für 64-Bit-Computer.

Angeben der Assemblybindung in Konfigurationsdateien

Sie verwenden dasselbe XML-Format, um Bindungsumleitungen anzugeben, unabhängig davon, ob es sich in der App-Konfigurationsdatei, in der Computerkonfigurationsdatei oder in der Herausgeberrichtliniendatei befindet. Verwenden Sie das <bindingRedirect-Element> , um eine Assemblyversion an eine andere umzuleiten. Das oldVersion Attribut kann eine einzelne Assemblyversion oder einen Bereich von Versionen angeben. Das newVersion Attribut sollte eine einzelne Version angeben. Gibt beispielsweise an, <bindingRedirect oldVersion="1.1.0.0-1.2.0.0" newVersion="2.0.0.0"/> dass die Laufzeit Version 2.0.0.0 anstelle der Assemblyversionen zwischen 1.1.0.0 und 1.2.0.0 verwenden soll.

Im folgenden Codebeispiel wird eine Vielzahl von Bindungsumleitungsszenarien veranschaulicht. Das Beispiel gibt eine Weiterleitung für einen Versionsbereich von myAssembly und eine einzelne Bindungsweiterleitung für mySecondAssembly an. Außerdem wird festgelegt, dass die Herausgeberrichtliniendatei nicht die Bindungsumleitungen für myThirdAssemblyüberschreiben soll.

Zum Binden einer Assembly müssen Sie die Zeichenfolge "urn:schemas-microsoft-com:asm.v1" mit dem xmlns Attribut im <assemblyBinding-Tag> angeben.

<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>

Beschränken von Assemblybindungen auf eine bestimmte Version

Sie können das attribut appliesTo für das <assemblyBinding>element in einer App-Konfigurationsdatei verwenden, um Assemblybindungsverweise auf eine bestimmte Version von .NET Framework umzuleiten. Dieses optionale Attribut verwendet eine .NET Framework-Versionsnummer, um anzugeben, auf welche Version sie angewendet wird. Wenn kein appliesTo-Attribut angegeben ist, gilt das element <assemblyBinding> für alle Versionen von .NET Framework.

Um beispielsweise die Assemblybindung für eine .NET Framework 3.5-Assembly umzuleiten, fügen Sie den folgenden XML-Code in die App-Konfigurationsdatei ein.

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

Sie sollten Umleitungsinformationen in der Versionsreihenfolge eingeben. Geben Sie beispielsweise Informationen zur Assemblybindungsumleitung für .NET Framework 3.5-Assemblys ein, gefolgt von .NET Framework 4.5-Assemblys. Geben Sie schließlich Informationen zur Assemblybindungsumleitung für jede .NET Framework-Assemblyumleitung ein, die das Attribut appliesTo nicht verwendet und daher für alle Versionen von .NET Framework gilt. Wenn ein Konflikt bei der Umleitung vorliegt, wird die erste übereinstimmende Umleitungsanweisung in der Konfigurationsdatei verwendet.

Wenn Sie beispielsweise einen Verweis auf eine .NET Framework 3.5-Assembly und einen anderen Verweis auf eine .NET Framework 4-Assembly umleiten möchten, verwenden Sie das Muster, das im folgenden Pseudocode dargestellt ist.

<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>

Siehe auch