.NET プロジェクトで依存関係の更新を管理する

完了

遅かれ早かれ、新しいバージョンのライブラリに更新することが必要になります。 関数が非推奨とマークされていたり、使用しているパッケージの新しいバージョンに新機能が存在していたりするかもしれません。

ライブラリの更新を試みる前に、次の事項を考慮してください。

  • 更新の種類: どのような種類の更新が利用可能ですか? それは小さなバグの修正か。 自分に必要な新しい機能が追加されているか。 コードへの破壊的変更があるか。 "セマンティック バージョニング" と呼ばれるシステムを使用して、更新の種類を伝えることができます。 開発者は、ライブラリのバージョン番号の表記方法によって、自分が扱っている更新の種類を知ることができます。
  • プロジェクトが正しく構成されているか: .NET プロジェクトを構成して、必要な種類の更新のみを受け取るよう構成できます。 特定の種類の更新が使用できる場合にのみ、更新を実行します。 この方法をお勧めします。不測の事態にさらされるリスクがないからです。
  • セキュリティの問題: プロジェクトの依存関係を将来にわたって管理するには、発生する可能性のある問題を認識している必要があります。 たとえば、脆弱性が検出されると問題が発生します。 理想的なのは、ダウンロードできるパッチがリリースされることです。 .NET Core ツールは、ライブラリに対して "監査" を実行して更新の必要なパッケージがあるかどうかを確認するのに役立ちます。 また、問題を修正するための適切な措置を講じることもできます。

セマンティック バージョニングを使用する

"セマンティック バージョニング" と呼ばれる業界標準があり、これは自分や他の開発者がライブラリに対して行おうとしている変更の種類を表現する方法です。 セマンティック バージョニングは、パッケージにバージョン番号があり、そのバージョン番号が次のセクションに分割されていることを確証することで機能します。

  • メジャー バージョン: 左端の番号。 たとえば、1.0.01 です。 この数値が変更されるということは、コードに "破壊的変更" が発生する可能性があることを意味します。 場合によっては、コードの一部を書き直す必要があります。
  • マイナー バージョン: 真ん中の番号。 たとえば、1.2.02 です。 この数値の変更は、機能が追加されたことを意味します。 コードは引き続き機能します。 通常、更新を受け入れても安全です。
  • 修正プログラムのバージョン: 右端の番号。 たとえば、1.2.33 です。 この数字が変更された場合、コードの何らかの問題を機能するように修正する変更が適用されたことを意味します。 更新を受け入れても安全です。

次の表は、バージョンの種類ごとにバージョン番号がどのように変わるかを示しています。

種類 変更内容
メジャー バージョン 1.0.02.0.0 に変更される
マイナー バージョン 1.1.11.2.0 に変更される
パッチ バージョン 1.0.11.0.2 に変更される

多くの会社や開発者がこのシステムを使用しています。 パッケージを発行して NuGet レジストリにプッシュする場合は、セマンティック バージョニングに従う必要があります。 NuGet レジストリからパッケージをダウンロードするだけの場合でも、これらのパッケージがセマンティック バージョニングに従っていることが想定されます。

パッケージに変更を加えると、リスクが生じる可能性があります。たとえば、バグによってビジネスが悪影響を受ける可能性があるというリスクがあります。 リスクによっては、コードの一部を書き換えることが必要な場合があります。 コードの書き直しには時間とコストがかかります。

更新方法

.NET 開発者は、.NET に必要な更新動作を伝えることができます。 リスクの観点から、更新について考えてみます。 いくつかの方法を次に示します。

  • メジャー バージョン: 最新のメジャー バージョンが公開されたらすぐに更新してかまいません。自分の側でコードを変更することが必要になる可能性があるという事実を受け入れます。
  • マイナー バージョン。新しい機能が追加されることを受け入れます。 コードの破壊的変更は受け入れません。
  • パッチ バージョン: 受け入れる更新はバグ修正のみです。

新しいまたはより小さい .NET プロジェクトを管理している場合は、更新戦略の定義方法に余裕を持たせることができます。 たとえば、常に最新バージョンに更新できます。 より複雑なプロジェクトの場合は、もっと微妙な違いがありますが、それについては将来のモジュールのために残しておきます。

一般に、更新する依存性が小さいほど、依存関係が少なくなり、更新プロセスが簡単になる可能性が高くなります。

更新用にプロジェクト ファイルを構成する

1 つ以上の依存関係を追加する場合は、プロジェクトの復元、ビルド、または実行時に予測可能な動作が得られるようにプロジェクト ファイルを構成します。 パッケージに対して採用する方法を伝えることができます。 NuGet には、"バージョン範囲" と "浮動バージョン" の概念があります。

バージョン範囲は、解決するバージョンの特定の範囲を示すために使用できる特別な表記法です。

表記 適用されるルール 説明
1.0 x >= 1.0 最小バージョン (示されている値を含む)
(1.0,) x > 1.0 最小バージョン (示されている値を含まない)
[1.0] x == 1.0 正確なバージョンの一致
(,1.0] x ≤ 1.0 最大バージョン (示されている値を含む)
(,1.0) x < 1.0 最大バージョン (示されている値を含まない)
[1.0,2.0] 1.0 ≤ x ≤ 2.0 正確な範囲 (示されている値を含む)
(1.0,2.0) 1.0 < x < 2.0 正確な範囲 (示されている値を含まない)
[1.0,2.0) 1.0 ≤ x < 2.0 示されている値を含む最小バージョンと示されている値を含まない最大バージョンの組み合わせ
(1.0) 無効 無効

NuGet では、メジャー、マイナー、パッチ、プレリリースの番号のサフィックス部分に浮動バージョン表記を使用することもサポートされています。 この表記はアスタリスク (*) です。 たとえば、バージョン仕様 6.0.* は、"最新の 6.0.x バージョンを使用する" を示します。別の例として、4.* は、"最新の 4.x バージョンを使用する" を示します。浮動バージョンを使用すると、最新バージョンの依存関係で最新の状態を維持しながら、プロジェクト ファイルへの変更を減らすことができます。

Note

浮動表記のいずれかを使用するのではなく、特定のバージョンをインストールすることをお勧めします。 特定のバージョンをインストールすると、依存関係の更新を明示的に要求しない限り、ビルドを確実に繰り返すことができます。

浮動バージョンを使用している場合、そのバージョン パターンに一致するパッケージの最新バージョンが NuGet によって解決されます。 次の例では、6.0.* は、6.0 で始まるパッケージの最新バージョンになります。 そのバージョンは 6.0.1 です。

フローティング バージョンが要求される際の最新バージョンの選択を示す図。

メジャー、マイナー、またはパッチ バージョン用に構成できる例をいくつか以下に示します。

<!-- Accepts any version 6.1 and later. -->
<PackageReference Include="ExamplePackage" Version="6.1" />

<!-- Accepts any 6.x.y version. -->
<PackageReference Include="ExamplePackage" Version="6.*" />
<PackageReference Include="ExamplePackage" Version="[6,7)" />

<!-- Accepts any later version, but not including 4.1.3. Could be
     used to guarantee a dependency with a specific bug fix. -->
<PackageReference Include="ExamplePackage" Version="(4.1.3,)" />

<!-- Accepts any version earlier than 5.x, which might be used to prevent pulling in a later
     version of a dependency that changed its interface. However, we don't recommend this form because determining the earliest version can be difficult. -->
<PackageReference Include="ExamplePackage" Version="(,5.0)" />

<!-- Accepts any 1.x or 2.x version, but not 0.x or 3.x and later. -->
<PackageReference Include="ExamplePackage" Version="[1,3)" />

<!-- Accepts 1.3.2 up to 1.4.x, but not 1.5 and later. -->
<PackageReference Include="ExamplePackage" Version="[1.3.2,1.5)" />

古くなったパッケージを検索して更新する

dotnet list package --outdated コマンドを実行すると、古くなったパッケージが一覧表示されます。 このコマンドは、より新しいバージョンのパッケージがいつ使用可能になっているか確認するのに役立ちます。 コマンドからの一般的な出力を以下に示します。

Top-level Package      Requested   Resolved   Latest
> Humanizer            2.7.*       2.7.9      2.8.26

出力内の列の名前の意味は次のとおりです。

  • Requested:指定したバージョンまたはバージョン範囲。
  • Resolved:指定されたバージョンに一致する、プロジェクトに対してダウンロードされた実際のバージョン。
  • Latest: NuGet からの更新の最新バージョン。

推奨されるワークフローは、次のコマンドをこの順序で実行することです。

  1. dotnet list package --outdated を実行する。 このコマンドを実行すると、古くなったパッケージがすべて一覧表示されます。 RequestedResolvedLatest 列で情報が提供されます。
  2. dotnet add package <package name> を実行します。 このコマンドを実行すると、最新バージョンへの更新が試行されます。 必要に応じて、--version=<version number/range> を渡すことができます。