Wann sollte copy-local auf true gesetzt werden und wann nicht?

75

Ich frage mich, ob es Heuristiken gibt, wann copy-local=trueReferenzen festgelegt werden sollen.

Wenn referenzierte Typen nur intern verwendet werden, kann ich festlegen copy-local, trueaber wenn referenzierte Typen als Parameter oder Rückgabewerte angezeigt werden, auf die ich festgelegt habe copy-local, falseund angeben, dass auf eine bestimmte Version der Abhängigkeit verwiesen werden soll, wenn meine Bibliothek verwendet werden soll?

Kann mir das jemand erklären?

Lichtecht
quelle

Antworten:

68

Lokales Kopieren ist wichtig für Bereitstellungsszenarien und -tools. In der Regel sollten Sie CopyLocal = True verwenden, wenn die Referenz nicht im GAC enthalten ist.

Lokal kopieren bedeutet im Wesentlichen, dass ich diese DLL manuell bereitstellen muss, damit meine Anwendung funktioniert. Wenn es falsch ist, bedeutet es im Wesentlichen "Ich bin auf eine andere Komponente angewiesen, die separat installiert oder verkettet werden muss, die DLL ist einfach schon da".

JaredPar
quelle
1
Wie wäre es mit dem Fall, dass ich eine Dienstprogrammbibliothek MyUtils habe, die LibX (nicht in gac) intern verwendet und keine LibX-spezifischen Typen verfügbar macht. Dort würde ich copy-local auf true setzen. Wenn ich jedoch LibX-Typen aus MyUtils verfügbar mache, müsste ich ref. LibX auch von ProjectA, das MyUtils no verwendet?
Fadeproof
Sollte ich in diesem Fall copy-local auf false setzen, da ich sowohl LibX als auch MyUtils von ProjectA referenzieren müsste?
Fadeproof
21

Copy local wurde wirklich implementiert, um das lokale Debuggen zu unterstützen. Wenn Sie Ihre Anwendung für Paket und Bereitstellung erstellen, sollten Sie Ihre Projekte in demselben Ausgabeordner erstellen und sicherstellen, dass Sie alle Referenzen haben, die Sie dort benötigen.

CopyLocal ist besonders beim Erstellen großer Quellbäume ein Problem. Es gab eine verwandte Frage zum Deaktivieren von CopyLocal hier auf SO. Sie können sie unter Wie überschreibe ich die Einstellung CopyLocal (privat) für Referenzen in .NET von MSBUILD sehen . Sowie Best Practices für große Lösungen in Visual Studio (2008).

Ich habe im Artikel MSBuild: Best Practices zum Erstellen zuverlässiger Builds, Teil 2, darüber geschrieben, wie mit dem Erstellen großer Quellbäume umgegangen werden soll .

Kurz gesagt würde ich sagen, deaktivieren Sie CopyLocal, wenn das Kopieren von Dateien dazu führt, dass Ihre Builds mehr Zeit in Anspruch nehmen, als Sie für jeden Build ausgeben möchten.

Sagte Ibrahim Hashimi
quelle
3
Wäre es besser zu sagen, dass "CopyLocal NUR deaktivieren, wenn Sie die Ausgabe ändern, um Ihre Projekte in denselben Ausgabeordner zu erstellen, und sicherstellen, dass Sie alle Referenzen haben, die Sie dort benötigen."?
Michael Freidgeim
@ MichaelFreidgeim: Hast du eine Antwort auf deine Frage gefunden?
Dave New
15

Es geht wirklich um die Zielumgebung. Wenn copy local falsch ist, sagen Sie, dass die Assembly bereits in der Zielumgebung (normalerweise im GAC) vorhanden ist. Wenn Sie den Wert auf "true" setzen, wird sichergestellt, dass er in der Ausgabe Ihres Builds angezeigt wird, sodass die Bereitstellung in der Zielumgebung einfacher wird.

Kent Boogaart
quelle
8

Lesen Sie die folgende MSDN-Referenz, in der das Verhalten von CopyLocal ausführlich erläutert wird.

Projektreferenzen

Leider gibt es einige Macken, und CopyLocal muss nicht wie erwartet für Assemblyreferenzen in sekundären Assemblys funktionieren, die wie unten gezeigt strukturiert sind.

  • MainApp.exe
    • MyLibrary.dll
      • ThirdPartyLibrary.dll (wenn im GAC CopyLocal nicht in den Ordner MainApp bin kopiert wird)

Dies macht xcopy-Bereitstellungen schwierig, wenn Sie nicht vorhaben, die Assembly eines Drittanbieters im GAC auf dem Zielcomputer zu installieren.

jpierson
quelle
1
Ich habe den Link aktualisiert und wünschte, Microsoft hätte ihn nach dem Verschieben umgeleitet.
Jpierson
2

Diese Option wirkt sich nur auf die Erstellungsphase aus. Es wird nur der Verweis auf das lokale Verzeichnis der erstellten Assembly kopiert.

Wenn eine andere Assembly (T) eine Methode aus der Assembly verwenden möchte, die Sie erstellen (A), die einen Rückgabetyp oder Parameter von einer anderen Assembly (R) hat, auf die verwiesen wird, sollte sie (T) auf diese Assembly (R) zugreifen können. Möglicherweise ist dies ohne besondere Maßnahmen möglich, wenn die referenzierte Baugruppe (R) in GAC installiert ist. Andernfalls wird eine lokale Kopie davon benötigt.

Mehrdad Afshari
quelle
3
Es macht ein bisschen mehr als das. Dies wirkt sich stark auf Bereitstellungsszenarien aus.
JaredPar
Ich glaube, es hat keinen Einfluss auf den Build, außer auf einen einfachen Dateikopiervorgang. Bitte korrigieren Sie mich, wenn es nicht stimmt.
Mehrdad Afshari
@Mehrad, es wirkt sich auf Build-Szenarien aus, ist aber mindestens gleichermaßen auf die Bereitstellung ausgerichtet.
JaredPar
@ JarPar: Oh natürlich. Das habe ich nicht bestritten. Ich dachte, es könnte etwas Besonderes in der Versammlung sein, von dem ich nichts wusste. Danke trotzdem.
Mehrdad Afshari
1

Die konservative Möglichkeit, CopyLocal auf false zu setzen, besteht darin, zu überprüfen, ob die Referenz im Ausgabepfad des Projekts gefunden wird. Dies sollte es Ihnen ermöglichen, einigen unangenehmen Laufzeitproblemen auszuweichen und gleichzeitig die Menge an E / A zu reduzieren.

Dabei habe ich CopyLocalFixer erstellt , den Sie für einen Ordner ausführen können. Ich habe es mit einem großen Build versucht, aber die Ergebnisse waren ehrlich gesagt nicht so beeindruckend. Ich denke, es kommt auf die Ordnerstruktur des Projekts an.

ollipekka
quelle