Es ist eine Eigenschaft zur Kompilierungszeit!
Eines der wichtigsten Dinge, die Sie wissen müssen, ist, dass "Spezifische Version" eine Eigenschaft ist, die zur Kompilierungszeit und nicht zur Laufzeit wirksam wird .
Worum geht es?
Wenn ein Projekt erstellt wird, müssen die Assemblyreferenzen des Projekts aufgelöst werden, um die physischen Assemblys zu finden, die das Buildsystem verwenden sollte. Wenn die Prüfung "Spezifische Version" durchgeführt wird (siehe Abschnitt "Wann wird" Spezifische Version "geprüft?"), Beeinflusst dies das Ergebnis des Assembly-Auflösungsprozesses:
- Das Build-System findet eine physische Assembly, die es möglicherweise verwenden kann
- Das Build-System vergleicht die Version der physischen Assembly mit der Assembly-Version, die in der .csproj-Datei für die Assembly-Referenz gespeichert ist
- Wenn die beiden Assemblyversionen genau identisch sind, ist der Auflösungsprozess erfolgreich und die gefundene physische Assembly wird für den Build verwendet
- Wenn die beiden Baugruppenversionen nicht übereinstimmen, wird die physische Baugruppe verworfen und der Auflösungsprozess wird fortgesetzt, indem die nächste potenzielle Baugruppe gesucht wird
- Wenn keine potenziellen physischen Baugruppen mehr gefunden werden können, schlägt der Auflösungsprozess fehl. Dies führt zu einer Compiler-Warnung (Warnung MSB3245), die Sie darüber informiert, dass die Referenz nicht aufgelöst werden konnte.
- Interessanterweise geht der Build dann weiter! Wenn der Code keine tatsächlichen Verweise auf die Assembly enthält, ist der Build erfolgreich (mit der zuvor erwähnten Warnung). Wenn der Code Verweise enthält, schlägt der Build mit einem Fehler fehl, der aussieht, als würde der Code unbekannte Typen oder Namespaces verwenden. Der einzige Hinweis, warum der Build wirklich fehlgeschlagen ist, ist die Warnung MSB3245.
Reihenfolge, in der Baugruppen aufgelöst werden
Die Reihenfolge, in der der Baugruppenauflösungsprozess potenzielle Baugruppen findet, scheint folgende zu sein:
- Die Assembly, auf die das
<HintPath>
Element in der .csproj-Datei verweist
- Der Projektausgabepfad
- Der GAC
Beachten Sie, dass der Auflösungsprozess zunächst versucht, die Assembly mit der höchsten Version aufzulösen, wenn im GAC mehrere Versionen der Assembly vorhanden sind. Dies ist nur wichtig, wenn die Prüfung "Spezifische Version" nicht durchgeführt wird.
Wann wird "Spezifische Version" aktiviert?
Visual Studio stützt seine Entscheidung, ob die Prüfung "Spezifische Version" durchgeführt werden soll, auf zwei Informationen, die in der .csproj-Datei enthalten sind:
- Das Vorhandensein oder Fehlen des
<SpecificVersion>
Elements und sein Wert (falls vorhanden)
- Das Vorhandensein oder Fehlen von Versionsinformationen in der Baugruppenreferenz
So sieht eine typische Assemblyreferenz mit Versionsinformationen aus:
<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>
Und so sieht die Assemblyreferenz ohne Versionsinformationen aus:
<Reference Include="Foo">
[...]
Die folgende Tabelle zeigt, wann die Prüfung "Spezifische Version" durchgeführt wird und wann nicht.
| Version information
| Present Not present
----------------------------+------------------------------
<SpecificVersion> |
- Present, has value True | Yes (1) Yes (check always fails) (2)
- Present, has value False | No (3) No (4)
- Not present | Yes (5) No (6)
Das Überraschende dabei ist, dass keine Überprüfung durchgeführt wird, wenn sowohl <SpecificVersion>
als auch Versionsinformationen fehlen (Fall 6). Ich hätte erwartet, dass die Prüfung durchgeführt wird und immer fehlschlägt (wie in Fall 2), da nach meinem Verständnis das Fehlen von <SpecificVersion>
den Standardwert "True" impliziert. Dies ist möglicherweise eine Besonderheit von Visual Studio 2010, in dem ich meine Tests durchgeführt habe.
Wenn Sie die Eigenschaften einer Assemblyreferenz in der Visual Studio-Benutzeroberfläche untersuchen (wählen Sie die Referenz aus und drücken Sie F4), gibt der Wert, den Sie für die Eigenschaft "Bestimmte Version" sehen, an, ob Visual Studio die "Bestimmte Version" ausführen wird oder nicht. prüfen. In Fall 6 zeigt die Benutzeroberfläche "True" an, obwohl das <SpecificVersion>
Element in der .csproj-Datei nicht vorhanden ist.
Nebenwirkungen von "Lokal kopieren"
Wenn die Eigenschaft "Lokal kopieren" auf "True" gesetzt ist, der Assemblyauflösungsprozess jedoch aufgrund der Prüfung "Spezifische Version" fehlschlägt, wird keine Assembly kopiert.
Referenzmaterial
PublicKeyToken=
Teil fehlt ). Wenn Sie die Tabelle gegen Ende meines Beitrags überprüfen, können Sie auch feststellen, dass die Versionsprüfung auch dann erfolgen kann, wenn dasVersion=
Teil im Assemblynamen in der .csproj fehlt. Frage 2: Ich gehe davon aus, dass der Assemblyname für den Vergleich verwendet wird, ja. Ich würde keine andere Quelle für die Informationen kennen.<SpecificVersion>
Tag vollständig weggelassen, das zuvor den Wert False hatte .Wenn Sie eine Referenz hinzufügen, zeichnet Visual Studio die [AssemblyVersion] der Assembly in der Projektdatei auf. Das ist wichtig. Wenn Sie beispielsweise ein Jahr später eine Fehlerbehebung erstellen, möchten Sie sicherstellen, dass Sie das Projekt mit genau derselben Version der Referenz neu erstellen, damit es sich um ein echtes Drop-In handelt. Sie erhalten eine Fehlermeldung, wenn sich die Referenzbaugruppe geändert hat.
Das ist aber nicht immer wünschenswert. Einige Programmierer lassen die Assembly-Version automatisch inkrementieren und generieren bei jeder Neuerstellung eine neue Version. Auch wenn sich die öffentliche Schnittstelle der Assembly nie geändert hat. Einige konfigurieren ihr Projekt mithilfe von Nuget, um Bibliotheken abzurufen, und lassen es die Bibliothek automatisch aktualisieren, wenn eine neue Version verfügbar ist. Sie möchten die Eigenschaft "Spezifische Version" auf "Falsch" setzen, um den Kompilierungsfehler zu unterdrücken.
Um die Konsequenzen zu verstehen, müssen Sie den gesamten Build des Programms neu bereitstellen, um Unfälle zu vermeiden. Versionsinkongruenzen zur Laufzeit stürzen das Programm ab und können nur mit einer
<bindingRedirect>
in der .config-Datei unterdrückten Datei unterdrückt werden .quelle
[AssemblyVersion]
wenn Assemblys keinen starken Namen haben.