Reduzieren von Paketabhängigkeiten mit „project.json“Reducing Package Dependencies with project.json

Dieser Artikel beschreibt, was Sie über das Reduzieren Ihrer Paketabhängigkeiten beim Erstellen von project.json-Bibliotheken wissen müssen.This article covers what you need to know about reducing your package dependencies when authoring project.json libraries. Am Ende dieses Artikels erfahren Sie, wie Ihre Bibliothek so zusammengesetzt wird, dass sie nur die Abhängigkeiten verwendet, die sie benötigt.By the end of this article, you will learn how to compose your library such that it only uses the dependencies it needs.

Warum dies wichtig istWhy it's Important

.NET Core ist ein Produkt, das aus NuGet-Paketen besteht..NET Core is a product made up of NuGet packages. Ein wichtiges Paket ist das .NETStandard.Library metapackage (.NETStandard.Library-Metapaket), wobei es sich um ein NuGet-Paket handelt, das aus anderen Paketen besteht.An essential package is the .NETStandard.Library metapackage, which is a NuGet package composed of other packages. Es stellt die Reihe von Paketen bereit, bei denen gewährleistet wird, dass sie auf mehreren .NET-Implementierungen wie z.B. .NET Framework, .NET Core und Xamarin/Mono funktionieren.It provides you with the set of packages that are guaranteed to work on multiple .NET implementations, such as .NET Framework, .NET Core and Xamarin/Mono.

Jedoch ist die Wahrscheinlichkeit hoch, dass Ihre Bibliothek nicht jedes einzelne Paket verwenden wird, das enthalten ist.However, there's a good chance that your library won't use every single package it contains. Beim Erstellen einer Bibliothek und Verteilen dieser Bibliothek über NuGet ist eine empfohlene Vorgehensweise das „Beschränken“ Ihrer Abhängigkeiten auf nur die Pakete, die Sie tatsächlich verwenden.When authoring a library and distributing it over NuGet, it's a best practice to "trim" your dependencies down to only the packages you actually use. Dies führt zu einem kleineren allgemeinen Speicherbedarf für NuGet-Pakete.This results in a smaller overall footprint for NuGet packages.

So gehen Sie vorHow to do it

Derzeit gibt es keinen offiziellen dotnet-Befehl, der Paketverweise beschränkt.Currently, there is no official dotnet command which trims package references. Stattdessen müssen Sie dies manuell tun.Instead, you'll have to do it manually. Der allgemeine Prozess sieht folgendermaßen aus:The general process looks like the following:

  1. Verweisen Sie auf NETStandard.Library Version 1.6.0 in einem dependencies-Abschnitt Ihrer project.json.Reference NETStandard.Library version 1.6.0 in a dependencies section of your project.json.
  2. Wiederherstellen von Paketen mit dotnet restore (Siehe Hinweis) über die Befehlszeile.Restore packages with dotnet restore (see note) from the command line.
  3. Prüfen Sie die Datei project.lock.json, und suchen Sie den Abschnitt NETSTandard.Library.Inspect the project.lock.json file and find the NETSTandard.Library section. Er befindet sich nahe dem Anfang der Datei.It's near the beginning of the file.
  4. Kopieren Sie alle unter dependencies aufgeführten Pakete.Copy all of the listed packages under dependencies.
  5. Entfernen Sie den .NETStandard.Library-Verweis, und ersetzen Sie ihn durch die kopierten Pakete.Remove the .NETStandard.Library reference and replace it with the copied packages.
  6. Entfernen Sie Verweise auf Pakete, die Sie nicht benötigen.Remove references to packages you don't need.

Auf eine der folgenden Weisen können Sie herausfinden, welche Pakete Sie nicht benötigen:You can find out which packages you don't need by one of the following ways:

  1. Ausprobieren:Trial and error. Bei dieser Methode entfernen Sie ein Paket, stellen es wieder her, nehmen zur Kenntnis, ob Ihre Bibliothek immer noch kompiliert, und wiederholen diesen Prozess.This involves removing a package, restoring, seeing if your library still compiles, and repeating this process.
  2. Verwenden eines Tools zum Ansehen von Verweisen wie z.B. ILSpy oder .NET Reflector, um zu sehen, was Ihr Code tatsächlich verwendet.Using a tool such as ILSpy or .NET Reflector to peek at references to see what your code is actually using. Anschließend können Sie Pakete entfernen, die nicht den Typen entsprechen, die Sie verwenden.You can then remove packages which don't correspond to types you're using.

BeispielExample

Stellen Sie sich vor, dass Sie eine Bibliothek geschrieben haben, die zusätzliche Funktionen für generische Sammlungstypen bereitstellt.Imagine that you wrote a library which provided additional functionality to generic collection types. Eine solche Bibliothek müsste von Paketen wie z.B. System.Collections abhängen, hängt möglicherweise aber überhaupt nicht von Paketen wie z.B. System.Net.Http ab.Such a library would need to depend on packages such as System.Collections, but may not at all depend on packages such as System.Net.Http. Daher wäre es gut, Paketabhängigkeiten auf nur das zu beschränken, was die Bibliothek tatsächlich benötigt.As such, it would be good to trim package dependencies down to only what this library required!

Um diese Bibliothek zu beschränken, beginnen Sie mit der project.json-Datei, und fügen Sie einen Verweis zu NETStandard.Library Version 1.6.0 hinzu.To trim this library, you start with the project.json file and add a reference to NETStandard.Library version 1.6.0.

{
    "version":"1.0.0",
    "dependencies":{
        "NETStandard.Library":"1.6.0"
    },
    "frameworks": {
        "netstandard1.0": {}
     }
}

Als Nächstes Wiederherstellen von Paketen mit dotnet restore (Siehe Hinweis), Überprüfen der project.lock.json Datei, und suchen Sie alle Pakete für wiederhergestellt NETSTandard.Library.Next, you restore packages with dotnet restore (see note), inspect the project.lock.json file, and find all the packages restored for NETSTandard.Library.

So sieht der entsprechende Abschnitt in der Datei project.lock.json aus, wenn auf netstandard1.0 abgezielt wird:Here's what the relevant section in the project.lock.json file looks like when targeting netstandard1.0:

"NETStandard.Library/1.6.0":{
    "type": "package",
    "dependencies": {
        "Microsoft.NETCore.Platforms": "1.0.1",
        "Microsoft.NETCore.Runtime": "1.0.2",
        "System.Collections": "4.0.11",
        "System.Diagnostics.Debug": "4.0.11",
        "System.Diagnostics.Tools": "4.0.1",
        "System.Globalization": "4.0.11",
        "System.IO": "4.1.0",
        "System.Linq": "4.1.0",
        "System.Net.Primitives": "4.0.11",
        "System.ObjectModel": "4.0.12",
        "System.Reflection": "4.1.0",
        "System.Reflection.Extensions": "4.0.1",
        "System.Reflection.Primitives": "4.0.1",
        "System.Resources.ResourceManager": "4.0.1",
        "System.Runtime": "4.1.0",
        "System.Runtime.Extensions": "4.1.0",
        "System.Text.Encoding": "4.0.11",
        "System.Text.Encoding.Extensions": "4.0.11",
        "System.Text.RegularExpressions": "4.1.0",
        "System.Threading": "4.0.11",
        "System.Threading.Tasks": "4.0.11",
        "System.Xml.ReaderWriter": "4.0.11",
        "System.Xml.XDocument": "4.0.11"
    }
}

Kopieren Sie als Nächstes die Paketverweise in den dependencies-Abschnitt der project.json-Datei der Bibliothek, und ersetzen Sie den NETStandard.Library-Verweis:Next, copy over the package references into the dependencies section of the library's project.json file, replacing the NETStandard.Library reference:

{
    "version":"1.0.0",
    "dependencies":{
        "Microsoft.NETCore.Platforms": "1.0.1",
        "Microsoft.NETCore.Runtime": "1.0.2",
        "System.Collections": "4.0.11",
        "System.Diagnostics.Debug": "4.0.11",
        "System.Diagnostics.Tools": "4.0.1",
        "System.Globalization": "4.0.11",
        "System.IO": "4.1.0",
        "System.Linq": "4.1.0",
        "System.Net.Primitives": "4.0.11",
        "System.ObjectModel": "4.0.12",
        "System.Reflection": "4.1.0",
        "System.Reflection.Extensions": "4.0.1",
        "System.Reflection.Primitives": "4.0.1",
        "System.Resources.ResourceManager": "4.0.1",
        "System.Runtime": "4.1.0",
        "System.Runtime.Extensions": "4.1.0",
        "System.Text.Encoding": "4.0.11",
        "System.Text.Encoding.Extensions": "4.0.11",
        "System.Text.RegularExpressions": "4.1.0",
        "System.Threading": "4.0.11",
        "System.Threading.Tasks": "4.0.11",
        "System.Xml.ReaderWriter": "4.0.11",
        "System.Xml.XDocument": "4.0.11"
    },
    "frameworks":{
        "netstandard1.0": {}
    }
}

Das sind ziemlich viele Pakete, die sicherlich nicht zum Erweitern von Sammlungstypen benötigt werden.That's quite a lot of packages, many of which which certainly aren't necessary for extending collection types. Sie können Pakete entweder manuell entfernen oder ein Tool wie z.B. ILSpy oder .NET Reflector verwenden, um zu bestimmen, welche Pakete Ihr Code tatsächlich verwendet.You can either remove packages manually or use a tool such as ILSpy or .NET Reflector to identify which packages your code actually uses.

So könnte ein eingeschränktes Paket aussehen:Here's what a trimmed package could look like:

{
    "dependencies":{
        "Microsoft.NETCore.Platforms": "1.0.1",
        "Microsoft.NETCore.Runtime": "1.0.2",
        "System.Collections": "4.0.11",
        "System.Linq": "4.1.0",
        "System.Runtime": "4.1.0",
        "System.Runtime.Extensions": "4.1.0",
        "System.Runtime.Handles": "4.0.1",
        "System.Runtime.InteropServices": "4.1.0",
        "System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
        "System.Threading.Tasks": "4.0.11"
    },
    "frameworks":{
        "netstandard1.0": {}
     }
}

Nun hat es einen geringeren Speicherbedarf als wenn es vom NETStandard.Library-Metapaket abhängen würde.Now, it has a smaller footprint than if it had depended on the NETStandard.Library metapackage.

Hinweis

Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands, such as dotnet build and dotnet run, that require a restore to occur. It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.