Nuget Pakete erstellen für Visual Studio Projekte

Veröffentlicht von

Meine Projektsolution wurde immer größer, zahlreiche Unterprojekte, gemeinsam genutzte Bibliotheken fanden sich darin vor. Daher bin ich nun dazu übergegangen, Unterprojekte, welche von mehreren Projekten verwendet werden, als Nuget Paket zu verpacken und diese über den Paketmanager einzubinden.

Warum?

Der Vorteil ist, dass diese nun nicht mehr in Quelltextform im Projekt herumliegen, von Visual Studio verwaltet und auch gebaut werden müssen. Einen Nachteil hat die Sache: Änderungen sind so nicht mehr schnell möglich und auch das Debugging ist nicht ohne weiteres möglich. Von daher nutze ich diese Möglichkeit bei Projekten, welche eine gewisse Reife haben und Änderungen sowie Debugging nur in Ausnahmefällen notwendig sind.

Das Herauslösen der Unterprojekte aus einer Übersolution und verpacken als Nuget hat noch einen weiteren Vorteil. Mit der Zeit haben sich Abhängigkeiten und Querverweise in die Projekte eingeschlichen. Ein “Add reference” ist schnell gesetzt und ein bisher unabhängiges Projekt hatte nun auf einmal eine Abhängigkeit gegen ein anderes Projekt. Diese habe ich im Zuge der Nugetisierung aufgelöst.

Auch ist Nuget nicht ohne Probleme und hat seine Eigenheiten. Aber nun legen wir los. Ich beschreibe hier die Erstellung von Nuget-Paketen, welche auf einem eigenen File-Server verwaltet werden.

Nuget Paket automatisch erstellen lassen

In Visual Studio 2017 kann man sich das Package direkt beim Build erstellen lassen. Dazu geht man in die Projekteigenschaften. Dort findet sich der Tag “Package”. Hier aktiviert man “Generate Nuget package on build”, trägt die Meta-Daten ein und anschließend wir bei jedem Build das Paket mit erstellt. Dies funktioniert allerdings nur, wenn man das neue Visual Studio Projekt-Format verwendet. Tut man dies nicht, dann taucht der Tab nicht auf.

Die Umstellung auf das neue Projektformat kann man in Erwägung ziehen. Eine Beschreibung gibt es hier.

Das neue Projektformat ist einfacher gestaltet und die Umstellung von einfachen Logikprojekten ist einfach. Sobald GUI ins Spiel kommt, sollte man von einer Umstellung absehen. Es funktioniert zwar prinzipiell, aber z.B. der Winforms-Designer lief danach nicht mehr. Auch die Möglichkeiten an Einstellungen für das Nuget-Paket werden hier nur teilweise in der Visual Studio GUI abgebildet. Wer mehr will, erstellt das Nuget-Paket von Hand.

Bei jedem Build wird nun zusätzlich die Nuget-Datei im Ausgabeverzeichnis mit abgelegt:

Nuget-Paket manuell erstellen

Mehr Kontrolle und Möglichkeiten hat man mit der manuellen Paketerstellung. Wobei sich das manuelle Erstellen nur auf die Meta-Datei, der .nuspec Datei bezieht. Das Paket baut uns weiterhin der NuGet-Paketmanager.

Diesen können wir hier herunterladen.

Beim Download handelt es sich um eine .exe Datei für die Kommandozeile. Diese habe ich lokal abgelegt und den Pfad der Path-Variable hinzugefügt. Somit kann ich diese dann von überall aufrufen.

Im Projektverzeichnis legen wir nun die Spec-Datei für das Nuget-Paket an. Dies geht über die Kommandozeile und dem Befehl:

nuget spec

Dies erzeugt eine .nuspec-Datei:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>$description$</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2018</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>
</package>

Viel Arbeit nimmt einem der Befehl nicht ab. Bereits bei der zweiten Lib hatte ich meine eigene Vorlage und habe diese verwendet. Es fehlen z.B. auch die Abhängigkeiten zu anderen Projekten, diese müssen wir später ebenfalls von Hand hinzufügen. Hier gilt es nun die Platzhalter auszufüllen. Bei der ID sollte man einen Namen wählen, welcher möglichst individuell ist. Ansonsten verwechselt Nuget gerne mal Pakete von unterschiedlichen Servern:

Hier hatte ich ein Nuget-Paket mit den Namen “Utilities” erstellt, welches auf einem internen File-Server liegt. Dummerweise gibt es auf dem offizielle Nuget-Server ein Paket mit gleichem Namen, so dass er hier updaten möchte.

Hier ein Beispiel eines meiner Pakete, die DAControls. Diese enthält GUI-Komponenten, welche ich projektübergreifend nutze.

Neben den einfachen Meta-Daten, werden hier noch Abhängigkeiten aufgeführt. Sowohl gegen eine Bibliothek von mir “DALogic” und auch Frameworkbibliotheken. Nuget kann die Abhängigkeit für die DALogic ebenfalls über Nuget auflösen und würde diese Bibliothek beim installieren von DAControls ebenfalls mitinstallieren. Vorausgesetzt es gibt ein solches Paket auf dem Nuget-Server. Alternativ kann man Nuget auch anweisen, solche Bibliotheken mit ins Nuget zu packen.

In Visual Studio bauen wir nun das Projekt. Anschließend können wir das Nuget-Paket erstellen. Dies geht ebenfalls über die Kommandozeile:

nuget pack DAControls.csproj  -properties Configuration=Release

Dies erstellt das Nuget-Paket in der Release-Version. Da ich mir solche Befehle schlecht merken kann, habe ich mir diesen in eine Batch-Datei gepackt. Nach dem Ausführen liegt das fertige Paket nun im gleichen Ordner.

Wer die Abhängigkeit von oben mit ins Paket hinein bekommen will, kann den Befehl erweitern:

nuget pack DAControls.csproj  -properties Configuration=Release -IncludeReferencedProjects

Der Parameter -IncludeReferencedProjects bewirkt, dass die referenzierte Datei mit in das Nuget aufgenommen wird. Ob die Aufnahme der abhängigen Bibliotheken sinnvoll ist oder nicht, kommt über auf den Einzelfall an. Kann die abhängige Bibliothek allein stehend verwendet werden? In diesem Fall erstelle ich für diese ebenfalls ein Nuget-Paket und lade es auf den Server.

File-Server als Nuget-Server

Da ich meine Pakete derzeit nur intern nutze, verwende ich einen File-Server als Nuget-Server. Das fertige Paket man mit folgendem Befehl auf dem File-Server abgelegt werden:

nuget add DAControls.1.0.0.nupkg -source \\server\path\nuget

Der Befehl kopiert das Nuget-Paket in eine Ordnerstruktur auf dem Server und legt die notwendigen Dateien an:

Dies sorgt auch gleich für die passende Versionierung. Legt man ein neues Paket an, wird die neue Version hinzugefügt, die alte bleibt erhalten und kann weiterhin genutzt werden.

Einbindung in Visual Studio

Kommen wir nun zum letzten Schritt. Die Pakete vom File-Server sollen auch über Visual Studio auffindbar und einbindbar sein. Dazu fügt man den lokalen Pfad in Visual Studio als Paketquelle hinzu:

Das wars! Der “Server” kann nun über die Auswahlbox in der Nuget-Oberfläche ausgewählt werden und die Pakete werden jetzt gefunden:

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.