Was ist die beste Vorgehensweise für "Lokal kopieren" und mit Projektreferenzen?

154

Ich habe eine große C # -Lösungsdatei (~ 100 Projekte) und versuche, die Erstellungszeiten zu verbessern. Ich denke, dass "Copy Local" in vielen Fällen für uns verschwenderisch ist, aber ich wundere mich über Best Practices.

In unserer .sln haben wir Anwendung A in Abhängigkeit von Baugruppe B, die von Baugruppe C abhängt. In unserem Fall gibt es Dutzende von "B" und eine Handvoll von "C". Da diese alle in der .sln enthalten sind, verwenden wir Projektreferenzen. Alle Assemblys sind derzeit in $ (SolutionDir) / Debug (oder Release) integriert.

Standardmäßig markiert Visual Studio diese Projektreferenzen als "Lokal kopieren", was dazu führt, dass jedes "C" für jedes "B", das erstellt wird, einmal in $ (SolutionDir) / Debug kopiert wird. Das scheint verschwenderisch. Was kann schief gehen, wenn ich "Lokal kopieren" ausschalte? Was machen andere Leute mit großen Systemen?

NACHVERFOLGEN:

Viele Antworten deuten darauf hin, dass der Build in kleinere SLN-Dateien aufgeteilt wird. Im obigen Beispiel würde ich zuerst die Foundation-Klassen "C" erstellen, gefolgt vom Großteil der Module "B" und dann einige Anwendungen. " EIN". In diesem Modell muss ich nicht-projektbezogene Verweise auf C von B haben. Das Problem, auf das ich dort stoße, ist, dass "Debug" oder "Release" in den Hinweispfad eingebrannt wird und ich meine Release-Builds von "B" erstelle. gegen Debug-Builds von "C".

Wie gehen Sie mit diesem Problem um, wenn Sie den Aufbau in mehrere SLN-Dateien aufteilen?

Dave Moore
quelle
9
Sie können Ihren Hinweispfad auf das Debug- oder Release-Verzeichnis verweisen lassen, indem Sie die Projektdatei direkt bearbeiten. Verwenden Sie $ (Konfiguration) anstelle von Debug oder Release. Beispiel: <HintPath> .. \ output \ $ (Konfiguration) \ test.dll </ HintPath> Dies ist ein Problem, wenn Sie viele Referenzen haben (obwohl es für jemanden nicht schwierig sein sollte, ein Add-In zu schreiben schaffe das).
Ultravelocity
4
Ist 'Lokal kopieren' in Visual Studio dasselbe wie <Private>True</Private>in einem csproj?
Colonel Panic
Die Aufteilung von a .slnin kleinere bricht jedoch die Berechnung der automatischen Interdependenz von <ProjectReference/>s durch VS. Ich bin selbst von mehreren kleineren .slns zu einem großen .slngewechselt, nur weil VS auf diese Weise weniger Probleme verursacht. Vielleicht geht das Follow-up also von einer nicht unbedingt besten Lösung für die ursprüngliche Frage aus? ;-)
Binki
Nur aus Neugier. Warum die Dinge komplizieren und über 100 Projekte an erster Stelle haben? Ist das schlechtes Design oder was?
nützlichBee
@ColonelPanic Ja. Zumindest ändert sich dies auf der Festplatte, wenn ich diesen Schalter in der GUI ändere.
Zero3

Antworten:

85

In einem früheren Projekt habe ich mit einer großen Lösung mit Projektreferenzen gearbeitet und bin auch auf ein Leistungsproblem gestoßen. Die Lösung war dreifach:

  1. Setzen Sie die Eigenschaft Copy Local immer auf false und erzwingen Sie dies über einen benutzerdefinierten msbuild-Schritt

  2. Stellen Sie das Ausgabeverzeichnis für jedes Projekt auf dasselbe Verzeichnis ein (vorzugsweise relativ zu $ ​​(SolutionDir).

  3. Die Standard-cs-Ziele, die mit dem Framework ausgeliefert werden, berechnen die Referenzsätze, die in das Ausgabeverzeichnis des aktuell erstellten Projekts kopiert werden sollen. Da dies die Berechnung eines transitiven Abschlusses unter der Beziehung 'Referenzen' erfordert, kann dies werden SEHR kostspielig werden. Meine Problemumgehung bestand darin, das GetCopyToOutputDirectoryItemsZiel in einer gemeinsamen Zieldatei (z. B. Common.targets) neu zu definieren, die nach dem Import von in jedes Projekt importiert wird Microsoft.CSharp.targets. Das Ergebnis in jeder Projektdatei sieht folgendermaßen aus:

    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        ... snip ...
      </ItemGroup>
      <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
      <Import Project="[relative path to Common.targets]" />
      <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
           Other similar extension points exist, see Microsoft.Common.targets.
      <Target Name="BeforeBuild">
      </Target>
      <Target Name="AfterBuild">
      </Target>
      -->
    </Project>

Dies reduzierte unsere Erstellungszeit zu einem bestimmten Zeitpunkt von einigen Stunden (hauptsächlich aufgrund von Speicherbeschränkungen) auf einige Minuten.

Die Neudefinition GetCopyToOutputDirectoryItemskann durch Kopieren der Zeilen 2.438–2.450 und 2.474–2.524 von C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targetsnach erstellt werden Common.targets.

Der Vollständigkeit halber lautet die resultierende Zieldefinition dann:

<!-- This is a modified version of the Microsoft.Common.targets
     version of this target it does not include transitively
     referenced projects. Since this leads to enormous memory
     consumption and is not needed since we use the single
     output directory strategy.
============================================================
                    GetCopyToOutputDirectoryItems

Get all project items that may need to be transferred to the
output directory.
============================================================ -->
<Target
    Name="GetCopyToOutputDirectoryItems"
    Outputs="@(AllItemsFullPathWithTargetPath)"
    DependsOnTargets="AssignTargetPaths;_SplitProjectReferencesByFileExistence">

    <!-- Get items from this project last so that they will be copied last. -->
    <CreateItem
        Include="@(ContentWithTargetPath->'%(FullPath)')"
        Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"
            >
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>

    <CreateItem
        Include="@(_EmbeddedResourceWithTargetPath->'%(FullPath)')"
        Condition="'%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"
            >
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>

    <CreateItem
        Include="@(Compile->'%(FullPath)')"
        Condition="'%(Compile.CopyToOutputDirectory)'=='Always' or '%(Compile.CopyToOutputDirectory)'=='PreserveNewest'">
        <Output TaskParameter="Include" ItemName="_CompileItemsToCopy"/>
    </CreateItem>
    <AssignTargetPath Files="@(_CompileItemsToCopy)" RootFolder="$(MSBuildProjectDirectory)">
        <Output TaskParameter="AssignedFiles" ItemName="_CompileItemsToCopyWithTargetPath" />
    </AssignTargetPath>
    <CreateItem Include="@(_CompileItemsToCopyWithTargetPath)">
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(_CompileItemsToCopyWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(_CompileItemsToCopyWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>

    <CreateItem
        Include="@(_NoneWithTargetPath->'%(FullPath)')"
        Condition="'%(_NoneWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(_NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"
            >
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(_NoneWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(_NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>
</Target>

Mit dieser Problemumgehung fand ich es praktikabel, bis zu> 120 Projekte in einer Lösung zu haben. Dies hat den Hauptvorteil, dass die Erstellungsreihenfolge der Projekte weiterhin von VS bestimmt werden kann, anstatt dies manuell durch Aufteilen Ihrer Lösung zu tun .

Bas Bossink
quelle
Können Sie die vorgenommenen Änderungen beschreiben und warum? Meine Augäpfel sind nach einem langen Tag des Codierens zu müde, um zu versuchen, es selbst zurückzuentwickeln :)
Charlie Flowers
Wie wäre es mit dem Versuch, dies erneut zu kopieren und einzufügen? SO durcheinander wie 99% der Tags.
ZXX
@Charlie Flowers, @ZXX hat den Text so bearbeitet, dass er eine Beschreibung ist. Die XML konnte nicht gut zum Layout gebracht werden.
Bas Bossink
1
Aus Microsoft.Common.targets: GetCopyToOutputDirectoryItems Ruft alle Projektelemente ab, die möglicherweise in das Ausgabeverzeichnis übertragen werden müssen. Dies schließt Gepäckstücke aus transitiv referenzierten Projekten ein. Es scheint, dass dieses Ziel den vollständigen transitiven Abschluss von Inhaltselementen für alle referenzierten Projekte berechnet. Dies ist jedoch nicht der Fall.
Brans Ds
2
Es sammelt nur die Inhaltselemente von seinen unmittelbaren Kindern und nicht von Kindern von Kindern. Der Grund dafür ist, dass die von _SplitProjectReferencesByFileExistence verwendete ProjectReferenceWithConfiguration-Liste nur im aktuellen Projekt ausgefüllt und in den untergeordneten Projekten leer ist. Die leere Liste bewirkt, dass _MSBuildProjectReferenceExistent leer ist, und beendet die Rekursion. Es scheint also nicht nützlich zu sein.
Brans Ds
32

Ich werde Ihnen vorschlagen, die Artikel von Patric Smacchia zu diesem Thema zu lesen:

CC.Net VS-Projekte basieren auf der Option zum Kopieren lokaler Referenzassemblierungen, die auf true festgelegt ist. [...] Dies erhöht nicht nur die Kompilierungszeit erheblich (x3 bei NUnit), sondern bringt auch Ihre Arbeitsumgebung durcheinander. Last but not least birgt dies das Risiko, potenzielle Probleme zu versionieren. Übrigens gibt NDepend eine Warnung aus, wenn 2 Assemblys in 2 verschiedenen Verzeichnissen mit demselben Namen, aber nicht demselben Inhalt oder derselben Version gefunden werden.

Das Richtige ist, 2 Verzeichnisse $ RootDir $ \ bin \ Debug und $ RootDir $ \ bin \ Release zu definieren und Ihre VisualStudio-Projekte so zu konfigurieren, dass Assemblys in diesen Verzeichnissen ausgegeben werden. Alle Projektreferenzen sollten auf Assemblys im Debug-Verzeichnis verweisen.

Sie können diesen Artikel auch lesen , um die Anzahl Ihrer Projekte zu verringern und die Kompilierungszeit zu verbessern.

Julien Hoarau
quelle
1
Ich wünschte, ich könnte Smacchias Praktiken mit mehr als einer Gegenstimme empfehlen! Die Reduzierung der Anzahl der Projekte ist der Schlüssel, nicht die Aufteilung der Lösung.
Anthony Mastrean
23

Ich schlage vor, copy local = false für fast alle Projekte zu verwenden, mit Ausnahme des Projekts, das sich oben im Abhängigkeitsbaum befindet. Und für alle Referenzen in der obersten Menge kopieren Sie local = true. Ich sehe viele Leute, die vorschlagen, ein Ausgabeverzeichnis zu teilen. Ich denke, das ist eine schreckliche Idee, die auf Erfahrung basiert. Wenn Ihr Startprojekt Verweise auf eine DLL enthält, auf die jedes andere Projekt verweist, tritt irgendwann eine Verletzung von access \ shared auf, selbst wenn copy local = false für alles ist und Ihr Build fehlschlägt. Dieses Problem ist sehr ärgerlich und schwer zu finden. Ich empfehle dringend, sich von einem Shard-Ausgabeverzeichnis fernzuhalten und anstatt das Projekt oben in der Abhängigkeitskette zu haben, die erforderlichen Assemblys in den entsprechenden Ordner zu schreiben. Wenn Sie kein Projekt oben haben, dann würde ich eine Kopie nach dem Bau vorschlagen, um alles an den richtigen Ort zu bringen. Außerdem würde ich versuchen, die Leichtigkeit des Debuggens im Auge zu behalten. Alle exe-Projekte, die ich noch hinterlasse, sind copy local = true, damit das F5-Debugging funktioniert.

Aaron Stainback
quelle
2
Ich hatte die gleiche Idee und hoffte, jemanden zu finden, der hier genauso dachte; Ich bin jedoch gespannt, warum dieser Beitrag keine weiteren Upvotes enthält. Menschen, die nicht einverstanden sind: Warum sind Sie nicht einverstanden?
Bwerks
Nein, das kann nur passieren, wenn dasselbe Projekt zweimal erstellt wird. Warum wird die Verletzung \ access \ shared überschrieben, wenn es einmal erstellt wird und keine Dateien kopiert werden?
Paulm
Dies. Wenn der Entwicklungsworkflow das Erstellen eines Projekts der SLN erfordert, während ein anderes Projekt ausgeführt wird, das von der Lösung ausgeführt werden kann, ist es ein Chaos, wenn sich alles im selben Ausgabeverzeichnis befindet. In diesem Fall ist es viel besser, ausführbare Ausgabeordner zu trennen.
Martin Ba
10

Du hast Recht. CopyLocal wird Ihre Build-Zeiten absolut zunichte machen. Wenn Sie einen großen Quellbaum haben, sollten Sie CopyLocal deaktivieren. Leider ist es nicht so einfach, es sauber zu deaktivieren. Ich habe diese genaue Frage beantwortet zu deaktivieren Copylocal bei Wie kann ich Copylocal (Private) Einstellung für Referenzen in .NET von MSBUILD außer Kraft setzen . Hör zu. Sowie Best Practices für große Lösungen in Visual Studio (2008).

Hier sind einige weitere Informationen zu CopyLocal, wie ich es sehe.

CopyLocal wurde wirklich implementiert, um das lokale Debuggen zu unterstützen. Wenn Sie Ihre Anwendung für das Packen und Bereitstellen vorbereiten, sollten Sie Ihre Projekte in demselben Ausgabeordner erstellen und sicherstellen, dass Sie alle erforderlichen Referenzen haben.

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 .

Sagte Ibrahim Hashimi
quelle
8

Meiner Meinung nach ist eine Lösung mit 100 Projekten ein großer Fehler. Sie könnten Ihre Lösung wahrscheinlich in gültige logische kleine Einheiten aufteilen und so sowohl die Wartung als auch die Erstellung vereinfachen.

Bruno Shine
quelle
1
Bruno, siehe meine folgende Frage oben: Wenn wir in kleinere SLN-Dateien aufteilen, wie verwalten Sie den Aspekt Debug vs. Release, der dann in den Hinweispfad meiner Referenzen eingebrannt wird?
Dave Moore
1
Ich stimme diesem Punkt zu, die Lösung, mit der ich arbeite, hat ~ 100 Projekte, von denen nur eine Handvoll mehr als 3 Klassen haben. Die Bauzeiten sind schockierend, und meine Vorgänger haben die Lösung in 3 aufgeteilt, was den Fund völlig kaputt macht alle Referenzen und Refactoring. Das Ganze könnte in eine Handvoll Projekte passen, die in Sekundenschnelle erstellt würden!
Jon M
Dave, gute Frage. Wo ich arbeite, haben wir Skripte erstellt, die beispielsweise Abhängigkeiten für eine bestimmte Lösung erstellen und die Binärdateien an einer Stelle ablegen, an der die betreffende Lösung sie abrufen kann. Diese Skripte sind sowohl für Debug- als auch für Release-Builds parametrisiert. Der Nachteil ist die zusätzliche Zeit im Voraus, um diese Skripte zu erstellen, aber sie können für alle Apps wiederverwendet werden. Diese Lösung hat nach meinen Maßstäben gut funktioniert.
Jyoungdev
7

Ich bin überrascht, dass niemand die Verwendung von Hardlinks erwähnt hat. Anstatt die Dateien zu kopieren, wird ein Hardlink zur Originaldatei erstellt. Dies spart Speicherplatz und beschleunigt die Erstellung erheblich. Dies kann in der Befehlszeile mit den folgenden Eigenschaften aktiviert werden:

/ p: CreateHardLinksForAdditionalFilesIfPossible = true; CreateHardLinksForCopyAdditionalFilesIfPossible = true; CreateHardLinksForCopyFilesToOutputDirectoryIfPossible = true; CreateHardLinksForCopyLocalIfPossible = true;

Sie können dies auch einer zentralen Importdatei hinzufügen, damit alle Ihre Projekte diesen Vorteil nutzen können.

Matt Slagle
quelle
5

Wenn Sie die Abhängigkeitsstruktur über Projektreferenzen oder über Abhängigkeiten auf Lösungsebene definiert haben, können Sie "Lokal kopieren" sicher deaktivieren. Ich würde sogar sagen, dass dies eine bewährte Methode ist, da Sie MSBuild 3.5 verwenden können, um Ihren Build parallel auszuführen ( via / maxcpucount), ohne dass verschiedene Prozesse übereinander stolpern, wenn versucht wird, referenzierte Assemblys zu kopieren.

Torbjörn Gyllebring
quelle
4

Unsere "Best Practice" besteht darin, bei vielen Projekten Lösungen zu vermeiden. Wir haben ein Verzeichnis mit dem Namen "Matrix" mit aktuellen Versionen von Assemblys, und alle Referenzen stammen aus diesem Verzeichnis. Wenn Sie ein Projekt ändern und "Jetzt ist die Änderung abgeschlossen" sagen können, können Sie die Baugruppe in das Verzeichnis "Matrix" kopieren. Alle Projekte, die von dieser Assembly abhängen, haben also die aktuelle (= neueste) Version.

Wenn Sie nur wenige Projekte in Lösung haben, ist der Erstellungsprozess viel schneller.

Sie können den Schritt "Baugruppe in Matrixverzeichnis kopieren" mithilfe von Visual Studio-Makros oder mit "Menü -> Tools -> externe Tools ..." automatisieren.

TcKs
quelle
2

Wenn Sie CopyLocal = false festlegen, wird die Erstellungszeit verkürzt, es können jedoch während der Bereitstellung unterschiedliche Probleme auftreten.

Es gibt viele Szenarien, in denen Copy Local auf True gesetzt werden muss, z

  • Projekte auf höchster Ebene,
  • Abhängigkeiten der zweiten Ebene,
  • Durch Reflexion aufgerufene DLLs

Die möglichen Probleme, die in SO-Fragen beschrieben werden:
" Wann sollte copy-local auf true gesetzt werden und wann nicht? ",
" Fehlermeldung 'Einer oder mehrere der angeforderten Typen können nicht geladen werden. Rufen Sie die LoaderExceptions-Eigenschaft ab, um weitere Informationen zu erhalten.' "
Und   aaron-Stainback ‚s Antwort  auf diese Frage.

Meine Erfahrung mit dem Setzen von CopyLocal = false war NICHT erfolgreich. Siehe meinen Blog-Beitrag "NICHT ändern" Lokale Projektreferenzen kopieren auf "falsch", es sei denn, Sie verstehen Teilsequenzen. "

Die Zeit zur Lösung der Probleme übergewichtet die Vorteile der Einstellung von copyLocal = false.

Michael Freidgeim
quelle
Die Einstellung CopyLocal=Falsewird sicherlich einige Probleme verursachen, aber es gibt Lösungen für diese. Außerdem sollten Sie die Formatierung Ihres Blogs korrigieren, da es kaum lesbar ist. Dort zu sagen, dass "Ich wurde von <zufälliger Berater> von <zufälliger Firma> vor möglichen Fehlern während der Bereitstellung gewarnt", ist kein Argument. Sie müssen sich entwickeln.
Suzanne Dupéron
@ GeorgesDupéron, Die Zeit, um die Probleme zu lösen, übergewichtet die Vorteile der Einstellung von copyLocal = false. Die Bezugnahme auf den Berater ist kein Argument, sondern eine Anerkennung, und mein Blog erklärt die Probleme. Vielen Dank für Ihr Feedback bezüglich. Formatierung werde ich beheben.
Michael Freidgeim
1

Ich neige dazu, in ein gemeinsames Verzeichnis zu erstellen (z. B. .. \ bin), damit ich kleine Testlösungen erstellen kann.

kenny
quelle
1

Sie können versuchen, einen Ordner zu verwenden, in den alle Assemblys kopiert werden, die von Projekten gemeinsam genutzt werden. Erstellen Sie dann eine DEVPATH-Umgebungsvariable und legen Sie sie fest

<developmentMode developerInstallation="true" />

in der Datei machine.config auf der Workstation jedes Entwicklers fest. Sie müssen lediglich eine neue Version in Ihren Ordner kopieren, auf die die Variable DEVPATH verweist.

Teilen Sie Ihre Lösung nach Möglichkeit auch in einige kleinere Lösungen auf.

Aleksandar
quelle
Interessant ... Wie würde dies mit Debug- oder Release-Builds funktionieren?
Dave Moore
Ich bin nicht sicher, ob es eine geeignete Lösung zum Laden von Debug- / Release-Assemblys über einen DEVPATH gibt. Sie soll nur für gemeinsam genutzte Assemblys verwendet werden. Ich würde sie nicht für regelmäßige Builds empfehlen. Beachten Sie auch, dass Assembly-Version und GAC bei Verwendung dieser Technik überschrieben werden.
Aleksandar
1

Das ist vielleicht nicht die beste Übung, aber so arbeite ich.

Ich habe festgestellt, dass Managed C ++ alle Binärdateien in $ (SolutionDir) / 'DebugOrRelease' speichert. Also habe ich auch alle meine C # -Projekte dort abgeladen. Ich habe auch die Option "Lokal kopieren" aller Verweise auf Projekte in der Lösung deaktiviert. Ich hatte eine spürbare Verbesserung der Bauzeit in meiner kleinen 10-Projektlösung. Diese Lösung ist eine Mischung aus C # -, verwalteten C ++ -, nativen C ++ -, C # -Webdienst- und Installationsprojekten.

Vielleicht ist etwas kaputt, aber da ich nur so arbeite, merke ich es nicht.

Es wäre interessant herauszufinden, was ich kaputt mache.

jyoung
quelle
0

Normalerweise müssen Sie Local nur kopieren, wenn Sie möchten, dass Ihr Projekt die DLL verwendet, die sich in Ihrem Bin befindet, und nicht die, die sich an einem anderen Ort befindet (GAC, andere Projekte usw.).

Ich würde eher mit den anderen Leuten übereinstimmen, dass Sie auch versuchen sollten, wenn möglich, diese Lösung aufzubrechen.

Sie können Configuration Manager auch verwenden, um innerhalb dieser einen Lösung unterschiedliche Build-Konfigurationen vorzunehmen, mit denen nur bestimmte Projektgruppen erstellt werden.

Es erscheint seltsam, wenn sich alle 100 Projekte aufeinander verlassen. Sie sollten also in der Lage sein, sie entweder aufzubrechen oder Configuration Manager zu verwenden, um sich selbst zu helfen.

CubanX
quelle
0

Sie können Ihre Projektreferenzen auf die Debug-Versionen der DLLs verweisen lassen. Als in Ihrem msbuild-Skript können Sie das festlegen /p:Configuration=Release, sodass Sie eine Release-Version Ihrer Anwendung und aller Satelliten-Assemblys haben.

Bruno Shine
quelle
1
Bruno - ja, das funktioniert mit Projektreferenzen, was einer der Gründe ist, warum wir überhaupt eine 100-Projektlösung gefunden haben. Es funktioniert nicht auf Referenzen , wo ich auf die vorgefertigten Debug Versionen zu sehen - ich mit einem Release - App gegen Debug Baugruppen aufgebaut aufzuwickeln, was ein Problem ist
Dave Moore
4
Bearbeiten Sie Ihre Projektdatei in einem Texteditor und verwenden Sie $ (Konfiguration) in Ihrem Hinweispfad, z. B. <Hinweispfad> .. \ output \ $ (Konfiguration) \ test.dll </ Hinweispfad>.
Ultravelocity
0

Wenn die Referenz nicht im GAC enthalten ist, müssen wir Copy Local auf true setzen, damit die Anwendung funktioniert. Wenn wir sicher sind, dass die Referenz im GAC vorinstalliert wird, kann sie auf false gesetzt werden.

SharpGobi
quelle
0

Nun, ich weiß sicherlich nicht, wie die Probleme funktionieren, aber ich hatte Kontakt zu einer Build-Lösung, die sich selbst half, so dass alle erstellten Dateien mit Hilfe symbolischer Links auf eine Ramdisk gelegt wurden .

  • c: \ Lösungsordner \ bin -> Ramdisk r: \ Lösungsordner \ bin \
  • c: \ Lösungsordner \ obj -> Ramdisk r: \ Lösungsordner \ obj \

  • Sie können dem Visual Studio auch zusätzlich mitteilen, welches temporäre Verzeichnis es für den Build verwenden kann.

Eigentlich war das nicht alles, was es tat. Aber es hat mein Verständnis von Leistung wirklich getroffen.
100% Prozessorauslastung und ein riesiges Projekt in weniger als 3 Minuten mit allen Abhängigkeiten.


quelle