mcpField
D
dotnet-modernize

dotnet-modernize

github.com/wshaddix開発8679 回インストール35 週間前に更新
リポジトリ

dotnet-modernize について

既存の .NET コードから、古いフレームワークやパッケージ、API、未導入の慣行を見つけるスキルです。改善点を提案し、アップグレード自体は実行しません。

主な機能

  1. 01ターゲットフレームワークの確認
  2. 02非推奨パッケージの指摘
  3. 03旧式 API パターンの特定
  4. 04ビルド設定の不足確認
  5. 05セキュリティとコンプライアンス上の問題の提示

活用シーン

  1. 01サポート終了したターゲットフレームワークの発見
  2. 02パッケージ置き換え作業の計画
  3. 03古いコードパターンの特定
  4. 04セキュリティと保守上の課題の優先順位付け

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-modernize

インストール後、Claude Code で/dotnet-modernizeを入力して読み込まれたか確認します。

詳細

dotnet-modernize

既存の .NET コードを分析し、モダン化の機会を特定します。古いターゲットフレームワーク、非推奨のパッケージ、置き換えられた API パターン、最新のベストプラクティスの不足を検出します。各検出項目に対して、実行可能な推奨事項を提示します。

対象範囲の境界: このスキルが行うのは、機会の提示のみです。実際の移行パス、ポリフィル戦略、マルチターゲットのガイダンス、段階的なバージョンアップ手順については、[skill:dotnet-version-upgrade] と [skill:dotnet-multi-targeting] を参照してください。

前提条件: 最初に [skill:dotnet-version-detection] を実行して、現在の SDK、TFM、言語バージョンを確認してください。[skill:dotnet-project-analysis] を実行して、ソリューションの構造と依存関係を把握してください。

相互参照:最新のレイアウト規約については [skill:dotnet-project-structure]、非推奨パターンをアナライザーで検出する方法については [skill:dotnet-add-analyzers]、完全にモダン化されたプロジェクトの目標状態については [skill:dotnet-scaffold-project] を参照してください。


モダン化チェックリスト

既存のコードベースをこのチェックリストに沿って確認してください。各セクションでは、確認すべき項目と最新の代替手段を示します。

1. ターゲットフレームワーク

.csproj ファイル(または Directory.Build.props)の <TargetFramework> を確認します。

現在の TFM状態推奨事項
net8.0LTS — 2026 年 11 月までサポートnet10.0(LTS)へのアップグレードを計画
net9.0STS — 2026 年 5 月にサポート終了速やかに net10.0 にアップグレード
net7.0サポート終了直ちにアップグレード
net6.0サポート終了直ちにアップグレード
net5.0 以下サポート終了直ちにアップグレード
netstandard2.0/2.1サポート中(ライブラリ互換性)幅広い互換性のためにマルチターゲットにする場合は維持
netcoreapp3.1サポート終了直ちにアップグレード
.NET Framework 4.xレガシー移行の実現可能性を評価

すべてのプロジェクトをスキャンするには:

# Find all TFMs in the solution
find . -name "*.csproj" -exec grep -h "TargetFramework" {} \; | sort -u

# Check Directory.Build.props
grep "TargetFramework" Directory.Build.props 2>/dev/null

2. 非推奨または置き換えられたパッケージ

置き換えられたパッケージがないか、Directory.Packages.props(または各 .csproj ファイル)をスキャンします。

非推奨パッケージ置き換え先以降
Microsoft.Extensions.Http.PollyMicrosoft.Extensions.Http.Resilience.NET 8
Newtonsoft.Json(新規プロジェクト)System.Text.Json.NET Core 3.0 以降
Microsoft.AspNetCore.Mvc.NewtonsoftJson組み込みの STJ.NET Core 3.0 以降
Swashbuckle.AspNetCoreドキュメント生成には組み込みの OpenAPI(Microsoft.AspNetCore.OpenApi)を使用。Swagger UI、フィルター、コード生成を使用する場合は Swashbuckle を維持.NET 9
NSwag.AspNetCoreドキュメント生成には組み込みの OpenAPI を使用。クライアント生成や Swagger UI の機能を使用する場合は NSwag を維持.NET 9
Microsoft.Extensions.Logging.Log4Net.AspNetCore組み込みのロギングと Serilog または OpenTelemetry.NET Core 2.0 以降
Microsoft.AspNetCore.Authentication.JwtBearer(明示的な NuGet パッケージ)明示的な PackageReference を削除 — Microsoft.AspNetCore.App 共有フレームワークに含まれています.NET Core 3.0 以降
System.Data.SqlClientMicrosoft.Data.SqlClient.NET Core 3.0 以降
Microsoft.Azure.Storage.*Azure.Storage.*2020 年以降
WindowsAzure.StorageAzure.Storage.Blobs / Azure.Storage.Queues2020 年以降
Microsoft.Azure.ServiceBusAzure.Messaging.ServiceBus2020 年以降
Microsoft.Azure.EventHubsAzure.Messaging.EventHubs2020 年以降
EntityFramework(EF6)Microsoft.EntityFrameworkCore.NET Core 1.0 以降
RestSharp(古いバージョン)HttpClient + System.Text.Json.NET Core 以降
AutoMapper手動マッピングまたはソース生成マッパー推奨

非推奨パッケージをスキャンするには:

# List all package references
grep -rh "PackageVersion\|PackageReference" \
  Directory.Packages.props $(find . -name "*.csproj") 2>/dev/null | \
  grep -i "Include=" | sort -u

Newtonsoft.Json に関する注意: カスタムコンバーターや JObject 操作など、Newtonsoft.Json を広範囲に使用している既存プロジェクトでは、直ちに移行してもメリットがない場合があります。検出対象としてフラグを立てたうえで、移行コストを評価してください。


3. 置き換えられた API パターン

最新の代替手段があるコードパターンを探します。

Startup.cs / Program.cs パターン

旧(.NET 6 より前):

public class Startup
{
    public void ConfigureServices(IServiceCollection services) { }
    public void Configure(IApplicationBuilder app) { }
}

最新(最小ホスティング):

var builder = WebApplication.CreateBuilder(args);
// ConfigureServices equivalent
var app = builder.Build();
// Configure equivalent
app.Run();
HttpClient の登録

旧:

services.AddHttpClient<MyService>(client =>
{
    client.BaseAddress = new Uri("https://api.example.com");
})
.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(300)));

最新(Microsoft.Extensions.Resilience を使用):

services.AddHttpClient<MyService>(client =>
{
    client.BaseAddress = new Uri("https://api.example.com");
})
.AddStandardResilienceHandler();
同期 I/O

検出対象: File.ReadAllText、Stream.Read、Async 接尾辞のない HttpClient。

最新: async バリアントを使用します。File.ReadAllTextAsync、Stream.ReadAsync、await httpClient.GetAsync() などです。

ホットパスでの文字列連結

検出対象: ログ記録やループ内での文字列連結(+)または String.Format。

最新: LoggerMessage ソースジェネレーターを使用した文字列補間、または StringBuilder を使用します。

レガシーなコレクションパターン

検出対象: Hashtable、ArrayList、非ジェネリックコレクション。

最新: Dictionary<TKey, TValue>、List<T> などのジェネリックコレクションを使用します。

ILogger パターン

旧:

_logger.LogInformation("Processing order {OrderId}", orderId);

最新(高パフォーマンス):

[LoggerMessage(Level = LogLevel.Information, Message = "Processing order {OrderId}")]
static partial void LogProcessingOrder(ILogger logger, string orderId);

4. 最新のビルド構成の不足

推奨されるビルド基盤が不足していないか確認します。

不足項目確認方法推奨事項
Central Package ManagementDirectory.Packages.props がない[skill:dotnet-project-structure] を参照してください
Directory.Build.propsプロパティが複数の .csproj ファイルに分散している共通プロパティを一元化します
.editorconfigリポジトリのルートに .editorconfig がない[skill:dotnet-project-structure] を参照してください
global.jsonSDK の固定がない再現可能なビルドのために追加します
NuGet の監査NuGetAudit プロパティがないDirectory.Build.props で有効にします
ロックファイルRestorePackagesWithLockFile がない復元を決定論的にするために有効にします
パッケージソースマッピングnuget.config に packageSourceMapping がないサプライチェーンのセキュリティのために追加します
アナライザーAnalysisLevel または EnforceCodeStyleInBuild がない[skill:dotnet-add-analyzers] を参照してください
SourceLinkSourceLink パッケージの参照がないデバッガーでソースへ移動できるように追加します
Nullable 参照型<Nullable> が有効になっていないグローバルに有効にします
.slnx.NET 9+ SDK で .sln を使用しているdotnet sln migrate で移行します

5. 非推奨の C# 言語パターン
古いパターン最新の置き換え言語バージョン
case を使用する switch ステートメントswitch 式C# 8
null != x / x != null によるチェックx is not nullC# 9
型が明らかな場合の new ClassName()ターゲット型指定の new()C# 9
ブロックスコープの名前空間ファイルスコープの名前空間C# 10
明示的なコンストラクターを持つ record class位置指定パラメーターを持つ recordC# 10
複数行文字列の手動連結raw 文字列リテラル("""...""")C# 11
INumber<T> の明示的なインターフェイス呼び出しジェネリック数学インターフェイスC# 11
[Flags] 列挙型の手動チェック改良された列挙型のパターンマッチングC# 11+
自然型を持たないラムダ式自然関数型C# 10+
ValueTask の手動ラップConfigureAwait パターンを使った Task / ValueTaskC# 全般
手動で実装したプライマリコンストラクタークラスclass / struct のプライマリコンストラクターC# 12
複数の if / else if による型チェックリストパターンを使った型の switchC# 11+
params T[]params ReadOnlySpan<T>、params コレクションC# 13
object を使ったロックSystem.Threading.LockC# 13

6. セキュリティとコンプライアンス
問題検出方法修正方法
既知の脆弱性dotnet list package --vulnerable影響を受けるパッケージを更新します
非推奨のパッケージdotnet list package --deprecated後継パッケージに置き換えます
古いパッケージdotnet list package --outdated更新を評価します
HTTPS リダイレクトの不足app.UseHttpsRedirection() がないパイプラインに追加します
HSTS の不足app.UseHsts() がない本番環境向けに追加します
ハードコードされたシークレットappsettings.json 内の接続文字列User Secrets または Key Vault を使用します
# Run all NuGet audits
dotnet list package --vulnerable --include-transitive
dotnet list package --deprecated
dotnet list package --outdated

最新化スキャンの実行

チェック項目を組み合わせ、体系的にスキャンします。

# 1. Check TFMs
echo "=== Target Frameworks ==="
find . -name "*.csproj" -exec grep -Hl "TargetFramework" {} \; | while read f; do
  echo "$f: $(grep -o '<TargetFramework[s]*>[^<]*' "$f" | head -1)"
done

# 2. Check for deprecated packages
echo "=== Package Audit ==="
dotnet list package --deprecated 2>/dev/null
dotnet list package --vulnerable --include-transitive 2>/dev/null

# 3. Check build infrastructure
echo "=== Build Infrastructure ==="
test -f Directory.Build.props && echo "OK: Directory.Build.props" || echo "MISSING: Directory.Build.props"
test -f Directory.Packages.props && echo "OK: Directory.Packages.props (CPM)" || echo "MISSING: Directory.Packages.props"
test -f .editorconfig && echo "OK: .editorconfig" || echo "MISSING: .editorconfig"
test -f global.json && echo "OK: global.json" || echo "MISSING: global.json"
test -f nuget.config && echo "OK: nuget.config" || echo "MISSING: nuget.config"

# 4. Check for old patterns in code
echo "=== Code Patterns ==="
grep -rl "class Startup" --include="*.cs" . 2>/dev/null && echo "FOUND: Legacy Startup.cs pattern"
grep -rl "Microsoft.Extensions.Http.Polly" --include="*.csproj" --include="*.props" . 2>/dev/null && echo "FOUND: Deprecated Polly package"
grep -rl "Swashbuckle" --include="*.csproj" --include="*.props" . 2>/dev/null && echo "FOUND: Swashbuckle (consider built-in OpenAPI for .NET 9+)"
grep -rl "System.Data.SqlClient" --include="*.csproj" --include="*.props" . 2>/dev/null && echo "FOUND: System.Data.SqlClient (use Microsoft.Data.SqlClient)"

モダナイゼーションの優先順位付け

すべてのモダナイゼーションが同じように緊急というわけではありません。影響度に基づいて優先順位を付けてください。

  1. セキュリティ -- 脆弱性のあるパッケージ、サポート終了の TFM(セキュリティパッチが提供されない)
  2. サポート性 -- 上流でのメンテナンスが行われていない非推奨のパッケージ
  3. パフォーマンス -- パフォーマンスに大きな影響を与えるパターン(同期処理から非同期処理への変換、ホットパスでのレガシーコレクション)
  4. 開発者エクスペリエンス -- ビルドインフラストラクチャ(CPM、アナライザー、editorconfig)によって日々のワークフローが改善されます
  5. コードスタイル -- 言語パターンの更新は優先度が最も低いものの、長期的には認知負荷を軽減します

次のステップ

このスキルはモダナイゼーションの機会を示します。アップグレードの実行については、以下を参照してください。

  • TFM のバージョンアップグレードと移行パス -- [skill:dotnet-version-upgrade]
  • マルチターゲティング戦略 -- [skill:dotnet-multi-targeting]
  • バージョン間のサポートに対応するポリフィルパッケージ -- [skill:dotnet-multi-targeting]
  • 不足しているビルドインフラストラクチャの追加 -- [skill:dotnet-project-structure]、[skill:dotnet-scaffold-project]
  • アナライザーの設定 -- [skill:dotnet-add-analyzers]
  • CI/CD の追加 -- [skill:dotnet-add-ci]

参考資料

コメント