dotnet-project-analysis について
.NET 開発エージェント向けのプロジェクト分析スキルです。ソリューション構成、プロジェクト参照、ビルド設定を調べ、重要なエントリーポイントを特定します。
主な機能
- 01ソリューションとプロジェクトの検出
- 02プロジェクト種別とテストの判定
- 03プロジェクト参照関係の整理
- 04共通ビルド・パッケージ設定の確認
- 05エントリーポイントと主要ファイルの特定
活用シーン
- 01未知の .NET リポジトリの構成把握
- 02プロジェクト参照やビルド設定の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill dotnet-project-analysisインストール後、Claude Code で/dotnet-project-analysisを入力して読み込まれたか確認します。
詳細
dotnet-project-analysis
.NET ソリューションの構造、プロジェクト参照、ビルド構成を分析します。このスキルは基盤となるもので、エージェントが意味のある .NET 開発作業を行うには、まずプロジェクトのレイアウトを理解する必要があります。
前提条件: まず [skill:dotnet-version-detection] を実行して、TFM と SDK のバージョンを特定してください。.csproj のない .NET 10 以降の単一ファイルアプリについては、代わりに [skill:dotnet-file-based-apps] を参照してください。
ステップ 1:ソリューションのルートを見つける
ワークスペース内でソリューションファイルを探します。現在のディレクトリから始めて、リポジトリのルートまで親ディレクトリをたどります。
.sln(従来の形式)
従来の MSBuild ソリューション形式です。プロジェクトのパスとビルド構成が含まれます。
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyApp", "src\MyApp\MyApp.csproj", "{GUID}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyApp.Tests", "tests\MyApp.Tests\MyApp.Tests.csproj", "{GUID}"
EndProject
Project("...") 行からプロジェクトエントリを抽出します。2 つ目の引用符付きの値がプロジェクト名、3 つ目の値が .csproj への相対パスです。
.slnx(新しい XML 形式)
新しい XML ベースのソリューション形式です(.NET 10 以降の SDK、Visual Studio 17.13 以降でサポート)。新規プロジェクトではこちらが推奨されます。
<Solution>
<Folder Name="/src/">
<Project Path="src/MyApp/MyApp.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/MyApp.Tests/MyApp.Tests.csproj" />
</Folder>
</Solution>
<Project Path="..." /> 要素からプロジェクトエントリを抽出します。ソリューションフォルダー(<Folder>)は論理的なグループ分けを示します。
ソリューションファイルがない場合
.sln または .slnx が見つからない場合は、.csproj ファイルを再帰的に検索します。次のように報告します:「ソリューションファイルが見つかりませんでした。N 個のプロジェクトファイルが見つかりました。dotnet new sln と dotnet sln add を使用してソリューションを作成することを検討してください。」
ステップ 2:各プロジェクトを分析する
ステップ 1 で見つかった各 .csproj の内容を読み取り、次の情報を抽出します。
プロジェクト SDK と種類
<Project Sdk="..."> 属性からプロジェクトの種類を特定できます。
| SDK | プロジェクトの種類 | 説明 |
|---|---|---|
Microsoft.NET.Sdk | クラスライブラリ/コンソール | 既定の SDK。<OutputType> を確認します |
Microsoft.NET.Sdk.Web | Web(API/MVC/Razor Pages) | ASP.NET Core の Web アプリケーション |
Microsoft.NET.Sdk.BlazorWebAssembly | Blazor WASM | クライアント側の Blazor(旧 SDK) |
Microsoft.NET.Sdk.Worker | Worker Service | バックグラウンドサービス/デーモン |
Microsoft.NET.Sdk.Razor | Razor クラスライブラリ | 共有 Razor コンポーネント |
Microsoft.Maui.Sdk または -android/-ios を含む TFM | MAUI | クロスプラットフォームのモバイル/デスクトップ |
カスタム SDK または Uno.Sdk | Uno Platform | クロスプラットフォーム UI(Uno の参照を確認します) |
出力の種類の判定
SDK が Microsoft.NET.Sdk の場合は、<OutputType> を確認して種類を判別します。
| OutputType | 意味 |
|---|---|
Exe | コンソールアプリケーション |
Library(または未指定) | クラスライブラリ |
WinExe | Windows デスクトップ(WPF/WinForms/WinUI) |
テストプロジェクトの判定
次のいずれかに該当する場合、そのプロジェクトはテストプロジェクトです。
<IsTestProject>true</IsTestProject>が設定されているxunit.v3、xunit、NUnit、MSTest.TestFramework、またはMicrosoft.NET.Test.Sdkへの PackageReference がある- プロジェクト名が
.Tests、.UnitTests、.IntegrationTests、または.TestUtilsで終わる
Blazor プロジェクトの判定
次のいずれかに該当する場合、そのプロジェクトは Blazor プロジェクトです。
- SDK が
Microsoft.NET.Sdk.BlazorWebAssembly <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" />がある- プロジェクトディレクトリに
.razorファイルがある - 起動時に
AddInteractiveServerComponents()またはAddInteractiveWebAssemblyComponents()を使用している
MAUI プロジェクトの判定
次のいずれかに該当する場合、そのプロジェクトは MAUI プロジェクトです。
<UseMaui>true</UseMaui>が設定されている- SDK が
Microsoft.Maui.Sdk - TFM にプラットフォーム固有のターゲットが含まれている:
net*-android、net*-ios、net*-maccatalyst、net*-windows(例:net8.0-android、net10.0-ios)
Uno Platform の判定
次のいずれかに該当する場合、そのプロジェクトは Uno Platform プロジェクトです。
- SDK が
Uno.SdkまたはUno.Sdk.Private Uno.WinUIまたはUno.UIへの PackageReference がある- TFM に Uno 固有のターゲットが含まれている(例:
net*-browserwasm、net*-desktop)
ステップ 3:プロジェクト参照をマッピングする
各 .csproj から <ProjectReference> 要素を読み取り、依存関係グラフを作成します。
<ItemGroup>
<ProjectReference Include="..\MyApp.Core\MyApp.Core.csproj" />
<ProjectReference Include="..\MyApp.Infrastructure\MyApp.Infrastructure.csproj" />
</ItemGroup>
依存関係グラフを作成して報告します。
Project Dependency Graph
========================
MyApp.Web (Web API)
-> MyApp.Core (Library)
-> MyApp.Infrastructure (Library)
-> MyApp.Core (Library)
MyApp.Tests (Test)
-> MyApp.Web (Web API)
-> MyApp.Core (Library)
問題を検出します。
- 循環参照:「Project A -> B -> A detected. This will cause build failures.」
- テストプロジェクトが他のテストプロジェクトを参照している場合:「Unusual -- test projects should reference production code, not other tests.」
- 深いネスト:4 レベルを超える深さは、過度な抽象化を示している可能性があります。
ステップ 4:集中管理されたビルド構成を検出する
Directory.Build.props
各プロジェクトのディレクトリからソリューションのルートまで、Directory.Build.props を検索します。これらのファイルは、そのディレクトリのサブツリーにあるすべてのプロジェクトに共通の MSBuild プロパティを設定します。
報告する一般的な共通プロパティ:
<TargetFramework>/<TargetFrameworks>-- 共通 TFM([skill:dotnet-version-detection] を参照)<LangVersion>-- C# 言語バージョン<Nullable>enable</Nullable>-- nullable 参照型<ImplicitUsings>enable</ImplicitUsings>-- 暗黙的なグローバル using<TreatWarningsAsErrors>true</TreatWarningsAsErrors>-- 警告を厳格に扱う設定<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>-- ビルド時のコードスタイル適用<AnalysisLevel>latest-all</AnalysisLevel>-- アナライザーの重大度<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>-- CPM の有効化を示す設定
報告:「<path> に Directory.Build.props が見つかりました。共通設定:[見つかったプロパティのリスト]。これらは <directory> 配下のすべてのプロジェクトに適用されます。」
Directory.Build.targets
同様に Directory.Build.targets を検索します。これらはプロジェクトの評価後に実行され、通常は次の内容を含みます。
- 共通の
<PackageReference>項目(例:すべてのプロジェクトに適用されるアナライザー) - プロジェクトの種類に基づく条件付きロジック
- カスタム MSBuild ターゲット
報告:「<path> に Directory.Build.targets が見つかりました。内容:[内容の要約]。」
複数の Directory.Build ファイル
異なる階層(例:ルートと src/)に複数の Directory.Build.props ファイルがある場合は、階層を報告します。
Build Configuration Hierarchy
==============================
/repo/Directory.Build.props (root: Nullable, ImplicitUsings, LangVersion)
/repo/src/Directory.Build.props (src: TargetFramework, TreatWarningsAsErrors)
/repo/tests/Directory.Build.props (tests: IsTestProject, test-specific settings)
注:内側のファイルは外側のファイルを自動的にインポートしません。チェーンが構成されているかどうかを確認するには、<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" /> を調べます。
ステップ 5:集中パッケージ管理(CPM)を検出する
Directory.Packages.props
ソリューションのルートからリポジトリのルート(またはファイルシステムのルート)に向かって上方向に、Directory.Packages.props を検索します。NuGet は階層に沿って CPM を解決するため、モノレポでは複数のソリューションを管理する Directory.Packages.props が親ディレクトリに存在する場合があります。また、CPM は別の場所で有効化されていることもあるため、階層内のすべての Directory.Build.props で <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> も確認します。
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.0" />
<PackageVersion Include="xunit.v3" Version="3.2.2" />
</ItemGroup>
</Project>
報告:
- CPM が有効:「集中パッケージ管理が有効です。パッケージのバージョンは
<path>にあるDirectory.Packages.propsで定義されています。個々の.csprojファイルでは、Version属性を指定せずに<PackageReference Include="..." />を使用しています。」 - パッケージ数:「中央管理されているパッケージは N 個です。」
- バージョンの上書き:個々のプロジェクトで
<PackageReference ... VersionOverride="...">が使われていないか確認し、例外として報告します。 - 継承された CPM:
Directory.Packages.propsがソリューションのルートより上にある場合は、「CPM は<path>(ソリューションルートより上)から継承されています。これはモノレポでは一般的です。」と記載します。
CPM が使用されていない場合
上方向への検索で Directory.Packages.props が見つからず、いずれの Directory.Build.props にも ManagePackageVersionsCentrally が設定されていない場合:
- 報告:「集中パッケージ管理は構成されていません。各プロジェクトが独自にパッケージのバージョンを定義しています。」
- 提案:「バージョンの一貫性を保つため、CPM の有効化を検討してください。設定方法は [skill:dotnet-project-structure] を参照してください。」
ステップ 6:追加の構成ファイルを検出する
.editorconfig
ソリューションのルートとその配下の階層で .editorconfig を確認します。以下を報告してください。
- 存在するかどうか
- 主なルール:インデント形式/サイズ、命名規則、重大度の上書き
- .NET 固有のセクション:
[*.cs]のdotnet_style_*およびcsharp_style_*ルール
nuget.config
ソリューションのルートから親ディレクトリへさかのぼりながら、nuget.config(大文字と小文字を区別しない)を検索します。NuGet は設定を階層的にマージするため(プロジェクト > ユーザー > マシン)、複数のファイルが有効な設定に反映される場合があります。見つかったファイルとその内容をすべて報告してください。
- 設定されているパッケージソース(例:nuget.org、プライベートフィード、ローカルフォルダー)
<packageSourceMapping>エントリ(サプライチェーンのセキュリティに関するベストプラクティス)<disabledPackageSources>エントリ- 注:「ユーザーレベル(
~/.nuget/NuGet/NuGet.Config)とマシンレベルの設定も、パッケージの解決に影響する場合があります。dotnet nuget list sourceを実行すると、マージ後の有効なソースを確認できます。」
global.json
[skill:dotnet-version-detection] によってすでに読み取り済みです。ここでは、関連する詳細を報告してください。
sdk.versionとsdk.rollForwardポリシー- 存在する場合は
msbuild-sdksセクション(カスタム SDK バージョン)
.config/dotnet-tools.json
ローカルツールマニフェストを確認します。インストールされているツールを報告してください。
dotnet-ef— Entity Framework Core ツールdotnet-format— コード整形nbgv— Nerdbank.GitVersioning- その他のツールとそのバージョン
ステップ 7:エントリーポイントと主要ファイルを特定する
プロジェクトの種類に応じて、最も重要なファイルをエージェントに案内します。
Web API/MVC/Razor Pages
- エントリーポイント:
Program.cs(トップレベルステートメント、サービス登録、ミドルウェアパイプライン) - 設定:
appsettings.json、appsettings.{Environment}.json - 起動処理:
builder.Servicesの登録とapp.Map*エンドポイントの定義を探します - エンドポイント:
Program.cs内またはEndpoints/ディレクトリ配下の*.csファイルにある Minimal API エンドポイント、Controllers/ディレクトリにあるコントローラーベースのエンドポイント
コンソールアプリケーション
- エントリーポイント:
Program.cs(トップレベルステートメントまたはstatic void Main) - 設定:
IHostBuilder/Generic Host を使用している場合はappsettings.json
Worker Service
- エントリーポイント:
builder.Services.AddHostedService<Worker>()を含むProgram.cs - ワーカー:
BackgroundServiceを継承し、ExecuteAsyncをオーバーライドするクラス
クラスライブラリ
- エントリーポイントなし:公開 API サーフェス(パブリッククラス/インターフェイス)を記録します
- 主要ファイル:主要な名前空間の型を探します
Blazor
- エントリーポイント:コンポーネント登録を含む
Program.cs - ルートコンポーネント:
App.razorまたはRoutes.razor - レイアウト:
Layout/またはShared/にあるMainLayout.razor - ページ:
@pageディレクティブを含む.razorファイル
MAUI
- エントリーポイント:
CreateMauiApp()を含むMauiProgram.cs - アプリシェル:ナビゲーション構造を定義する
AppShell.xaml - ページ:
Views/またはPages/ディレクトリ配下のファイル - プラットフォーム固有のファイル:Android、iOS、Windows、Mac Catalyst のフォルダーを含む
Platforms/ディレクトリ
テストプロジェクト
- テストファイル:
[Fact]、[Theory]、[Test]、または[TestMethod]属性を含む*.csファイル - フィクスチャ:
IClassFixture<T>またはICollectionFixture<T>を実装するクラス - 設定:統合テストで
WebApplicationFactory<T>を使用している箇所を探します
構造化出力形式
分析の完了後、次の形式で結果を提示します。
.NET Project Analysis Results
==============================
Solution: MyApp.slnx (or MyApp.sln)
Projects: 5 (2 libraries, 1 web API, 1 console, 1 test)
CPM: enabled (42 packages in Directory.Packages.props)
Shared Config: Directory.Build.props (Nullable, ImplicitUsings, LangVersion=14)
Code Style: .editorconfig present
Package Sources: nuget.org + private feed (packageSourceMapping configured)
Local Tools: dotnet-ef 10.0.0, nbgv 3.7.0
Project Dependency Graph
------------------------
MyApp.Api (Web API, net10.0) -> entry: src/MyApp.Api/Program.cs
-> MyApp.Core (Library)
-> MyApp.Infrastructure (Library)
-> MyApp.Core (Library)
MyApp.Console (Console, net10.0) -> entry: src/MyApp.Console/Program.cs
-> MyApp.Core (Library)
MyApp.Tests (Test, xUnit) -> entry: tests/MyApp.Tests/
-> MyApp.Api (Web API)
-> MyApp.Core (Library)
Key Files
---------
- Solution root: /repo/MyApp.slnx
- Shared props: /repo/Directory.Build.props
- Package versions: /repo/Directory.Packages.props
- API entry point: /repo/src/MyApp.Api/Program.cs
- API config: /repo/src/MyApp.Api/appsettings.json
エッジケース
混在するソリューション形式
.sln と .slnx の両方が存在する場合は、最新の形式である .slnx を優先します。注:「.sln と .slnx の両方が見つかりました。.slnx を主なソリューションとして使用します。.sln は古いツールとの互換性のために維持されている可能性があります。」
複数のソリューションがあるモノレポ
複数の .sln/.slnx ファイルが存在する場合は、すべて報告し、分析するソリューションをユーザーに確認します。リポジトリのルートにソリューションがある場合は、デフォルトでそれを使用します。
ソリューションに含まれていないプロジェクト
どのソリューションファイルからも参照されていない .csproj ファイルがある場合は、孤立ファイルとして報告します。「ソリューションに含まれていないプロジェクトファイルが N 件見つかりました。これらは実験用または未使用の可能性があります。」
条件付きの ProjectReferences
<ProjectReference> が <When> の内部にある場合、または Condition 属性がある場合:
<ProjectReference Include="..\MyApp.DevTools\MyApp.DevTools.csproj"
Condition="'$(Configuration)' == 'Debug'" />
「MyApp.DevTools への条件付き参照(Debug のみ)。」と報告します。
launchSettings.json がない Web プロジェクト
Web プロジェクトに Properties/launchSettings.json がない場合は、次のように記載します。「launchSettings.json が見つかりません。プロジェクトは既定の Kestrel 設定を使用します。開発用の起動プロファイルを追加することを検討してください。」