DLL sowohl im Mülleimer als auch im GAC, welche wird verwendet?

73

Wir haben eine Webanwendung, die auf vielen Websites mit nur Frontend-Änderungen bereitgestellt wird. Der gemeinsam genutzte Backend-Teil verfügt über eine DLL im GAC, sodass wir nur diese eine DLL aktualisieren müssen und alle Websites das Update erhalten.

Gibt es eine Möglichkeit, den GAC mit einer DLL im Ordner / bin zu überschreiben, um neue Funktionen zu testen, bevor sie veröffentlicht werden?

John Boker
quelle

Antworten:

84

Wenn es dieselbe Versionsnummer wie die referenzierte DLL hat, wird der GAC verwendet.

Wenn Sie die Versionsnummer erhöhen, die Website unter Bezugnahme auf die neue Versionsnummer neu erstellen, die neue Version im Verzeichnis / bin ablegen, wird diese DLL verwendet.

Wenn Sie die Versionsnummer nicht ändern möchten, haben Sie ziemlich viel Pech.

Wenn .NET stark benannte Assemblys lädt, versucht es zunächst zu entscheiden, welche Versionsnummer verwendet werden soll. Dies geschieht zuerst über die Referenz, dann nach Herausgeberrichtlinien und dann nach Bindungsumleitungen in der Konfigurationsdatei.

Danach sucht es im GAC nach der Assembly, dann in einer beliebigen angegebenen Codebasis und prüft verschiedene Dateisystemordner auf die DLL. Wenn bei einem dieser Schritte die richtige Versionsbaugruppe gefunden wird, wird sie gestoppt.

Wenn Sie die Versionsnummer Ihrer stark benannten Assembly nicht ändern, findet .NET die ursprüngliche im GAC und hört auf zu suchen. Beachten Sie, dass die Angabe einer Codebasis für Ihre Assembly nur dann hilfreich ist, wenn Sie eine Codebasis für Ihre Assembly angeben, da sie angehalten wird, wenn eine gefunden wird, und wenn Sie zuerst auch eine neue Versionsnummer angeben.

Adam Sills
quelle
2
Verstehe ich das richtig Wenn sich Version 1.0.0.0 im GAC befindet, ich aber mit Version 1.0.0.1 kompiliere und 1.0.0.1 in meiner BIN platziere, wird GAC ignoriert und BIN verwendet. Wenn ich die DLL aus meiner BIN entferne, wird 1.0.0.0 im GAC verwendet, obwohl ich mit 1.0.0.1 kompiliert habe.
J. Hendrix
2
Nein. Wenn Sie gegen eine Assembly mit starkem Namen kompilieren, ist die genaue Versionsnummer erforderlich, es sei denn, es sind Publisher-Richtlinien oder verbindliche Weiterleitungen verfügbar.
Adam Sills
2
Die Herausgeberrichtlinien und Bindungsumleitungen ermöglichen die Umleitung der Versionsnummer. Wenn Ihr Programm also gegen 1.0.0.0 kompiliert wurde und eine verbindliche Weiterleitung oder Herausgeberrichtlinie mit der Angabe 1.0.0.1 vorhanden ist, wird dies die gesuchte Version.
Adam Sills
2
Sobald die Versionsumleitung abgeschlossen ist, prüft der Assembly Loader (Fusion) verschiedene Positionen für die Assembly. Wenn es nicht die richtige Version findet, erhalten Sie eine Ausnahme.
Adam Sills
1
In Ihrem Fall haben Sie also gegen 1.0.0.1 kompiliert. Wenn diese Version nicht gefunden werden kann (egal wo sie aussieht), erhalten Sie eine Ausnahme.
Adam Sills
11

Ich konnte den GAC mit der Assembly im Ordner \ bin mithilfe des <codebase>Elements überschreiben .

Durch Angabe <codebase version="1.2.3.4" href="https://stackoverflow.com/bin/MyAssembly.dll" />in meiner Datei web.config kann ich meine Anwendung anweisen, diese Version anstelle der im GAC angegebenen Version zu verwenden.

Vielleicht möchten Sie auch einen Blick auf das <probing>Element werfen, um die Montageorte anzugeben?

IsolatedStorage
quelle
7
Sie sollten überprüfen, ob Ihre DLLs signiert sind oder nicht. GAC hat Vorrang vor Codebasis und Probe. Sobald die signierte Version in GAC gefunden wurde, wird sie gestoppt. Ich habe dies mit 4.0 getestet und das MSDN-Dokument ist korrekt, zuerst BindingRedirect, dann GAC, dann CodeBase, dann Probe for StrongName-Assemblys
CodeCowboyOrg
Dies funktioniert nur, wenn die verwendete Assemblyversion höher ist als die Version der Assembly im GAC. Wie im vorherigen Kommentar angegeben, können Sie die GAC-Auflösung nicht „überschreiben“, wenn die Versionsnummer mit der Baugruppe im GAC identisch ist. Das GAC bevorzugt. Siehe "Wie die Laufzeit Versammlungen findet"
Kissaki
2

Ich glaube, ich sage vielleicht das Gleiche wie Adam Sills, habe es aber für mein Verständnis umformuliert. Durch meine eigenen Tests sieht es so aus:

  • Wenn Ihre App mit Version 1.0.0.0 kompiliert wurde und 1.0.0.1 sich im GAC befindet, können Sie die DLL aus Ihrem / bin weglassen.
  • Wenn Ihre App mit Version 1.0.0.1 kompiliert wurde und 1.0.0.0 sich im GAC befindet, MÜSSEN Sie die DLL in Ihrem / bin ablegen, um den GAC zu ignorieren. Ein Fehler tritt auf, wenn die GAC-Version älter als die erforderliche Version Ihrer App ist, es sei denn, Sie fügen die neuere Version in Ihre / bin ein.

Ich hoffe das ist richtig ...

J. Hendrix
quelle
1
Das .NET Framework wird nicht Version Umleitung von starkem benannte Baugruppen automatisch tun, zumindest von .NET 3.5 (.NET 2.0 Runtime). Theoretisch könnte .NET 4 die Regeln ändern, aber ich bezweifle es.
Adam Sills
1
Vielen Dank! Ich sehe jetzt, warum meine Tests mit verschiedenen Versionen funktionierten. Ich dachte, der starke Name sei nur der Schlüssel, mit dem Sie ihn registrieren. Aber ich habe tatsächlich zwei Assemblys im GAC 1.0.0.0 und 1.0.0.1 registriert, beide mit demselben Token für den öffentlichen Schlüssel. Ich dachte, wenn ich denselben Schlüssel verwenden würde, würde 1.0.0.1 1.0.0.0 ersetzen. Dies scheint jedoch nicht der Fall zu sein. <br> Vielen Dank an @Adam für Ihre Hilfe!
J. Hendrix
0

Sie können Bindungsinformationen in der Protokolldatei mit dem Assembly Binding Log Viewer (Fuslogvw.exe) anzeigen, der im Windows Software Development Kit (SDK) enthalten ist.

s

BALKANGraph
quelle