Claude
Skills
Sign in
Back

dotnet-project-analysis

Included with Lifetime
$97 forever

Navigating .NET solution structure or build configuration. Analyzes .sln, .csproj, CPM.

General

What this skill does


```! find . -maxdepth 3 \( -name "*.csproj" -o -name "*.sln" -o -name "*.slnx" \) 2>/dev/null | head -20
```

# dotnet-project-analysis

Analyzes .NET solution structure, project references, and build configuration. This skill is foundational -- agents need to understand project layout before doing any meaningful .NET development work.

**Prerequisites:** Run [skill:dotnet-version-detection] first to determine TFM and SDK version. For .NET 10+ single-file apps without a `.csproj`, see [skill:dotnet-file-based-apps] instead.

---

## Step 1: Find the Solution Root

Look for solution files in the workspace, starting from the current directory and walking up to the repository root.

### .sln (Legacy Format)

The traditional MSBuild solution format. Contains project paths and build configurations.

```
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
```

Extract project entries from `Project("...")` lines. The second quoted value is the project name, the third is the relative path to the `.csproj`.

### .slnx (Modern XML Format)

The new XML-based solution format (supported in .NET 10+ SDK, Visual Studio 17.13+). Preferred for new projects.

```xml
<Solution>
  <Folder Name="/src/">
    <Project Path="src/MyApp/MyApp.csproj" />
  </Folder>
  <Folder Name="/tests/">
    <Project Path="tests/MyApp.Tests/MyApp.Tests.csproj" />
  </Folder>
</Solution>
```

Extract project entries from `<Project Path="..." />` elements. Solution folders (`<Folder>`) indicate logical grouping.

### No Solution File

If no `.sln` or `.slnx` is found, scan for `.csproj` files recursively. Report: "No solution file found. Discovered N project files. Consider creating a solution with `dotnet new sln` and `dotnet sln add`."

---

## Step 2: Analyze Each Project

For every `.csproj` discovered in Step 1, read its contents and extract the following.

### Project SDK and Type

The `<Project Sdk="...">` attribute identifies the project kind:

| SDK | Project Type | Description |
|-----|-------------|-------------|
| `Microsoft.NET.Sdk` | Class Library / Console | Default SDK, check for `<OutputType>` |
| `Microsoft.NET.Sdk.Web` | Web (API / MVC / Razor Pages) | ASP.NET Core web application |
| `Microsoft.NET.Sdk.BlazorWebAssembly` | Blazor WASM | Client-side Blazor (legacy SDK) |
| `Microsoft.NET.Sdk.Worker` | Worker Service | Background service / daemon |
| `Microsoft.NET.Sdk.Razor` | Razor Class Library | Shared Razor components |
| `Microsoft.Maui.Sdk` or TFMs with `-android`/`-ios` | MAUI | Cross-platform mobile/desktop |
| Custom or `Uno.Sdk` | Uno Platform | Cross-platform UI (check for Uno references) |

### Output Type Detection

If SDK is `Microsoft.NET.Sdk`, check `<OutputType>` to distinguish:

| OutputType | Meaning |
|-----------|---------|
| `Exe` | Console application |
| `Library` (or absent) | Class library |
| `WinExe` | Windows desktop (WPF/WinForms/WinUI) |

### Test Project Detection

A project is a test project if any of the following are true:
- `<IsTestProject>true</IsTestProject>` is set
- Has a PackageReference to `xunit.v3`, `xunit`, `NUnit`, `MSTest.TestFramework`, or `Microsoft.NET.Test.Sdk`
- Project name ends with `.Tests`, `.UnitTests`, `.IntegrationTests`, or `.TestUtils`

### Blazor Project Detection

A project is Blazor if:
- SDK is `Microsoft.NET.Sdk.BlazorWebAssembly`
- Has `<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" />`
- Has `.razor` files in the project directory
- Uses `AddInteractiveServerComponents()` or `AddInteractiveWebAssemblyComponents()` in startup

### MAUI Project Detection

A project is MAUI if:
- `<UseMaui>true</UseMaui>` is set
- SDK is `Microsoft.Maui.Sdk`
- TFM includes platform-specific targets: `net*-android`, `net*-ios`, `net*-maccatalyst`, `net*-windows` (e.g., `net8.0-android`, `net10.0-ios`)

### Uno Platform Detection

A project is Uno Platform if:
- SDK is `Uno.Sdk` or `Uno.Sdk.Private`
- Has PackageReference to `Uno.WinUI` or `Uno.UI`
- TFM includes Uno-specific targets (e.g., `net*-browserwasm`, `net*-desktop`)

---

## Step 3: Map Project References

Read `<ProjectReference>` elements from each `.csproj` to build the dependency graph.

```xml
<ItemGroup>
  <ProjectReference Include="..\MyApp.Core\MyApp.Core.csproj" />
  <ProjectReference Include="..\MyApp.Infrastructure\MyApp.Infrastructure.csproj" />
</ItemGroup>
```

Build a dependency graph and report it:

```
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)
```

Flag issues:
- **Circular references**: "Project A -> B -> A detected. This will cause build failures."
- **Test projects referencing other test projects**: "Unusual -- test projects should reference production code, not other tests."
- **Deep nesting**: More than 4 levels deep may indicate over-abstraction.

---

## Step 4: Detect Centralized Build Configuration

### Directory.Build.props

Search for `Directory.Build.props` starting from each project directory up to the solution root. These files set shared MSBuild properties across all projects in their directory subtree.

Common shared properties to report:
- `<TargetFramework>` / `<TargetFrameworks>` -- shared TFM (see [skill:dotnet-version-detection])
- `<LangVersion>` -- C# language version
- `<Nullable>enable</Nullable>` -- nullable reference types
- `<ImplicitUsings>enable</ImplicitUsings>` -- implicit global usings
- `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>` -- strict warnings
- `<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>` -- code style enforcement
- `<AnalysisLevel>latest-all</AnalysisLevel>` -- analyzer severity
- `<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>` -- CPM indicator

Report: "Found Directory.Build.props at `<path>`. Shared settings: [list properties found]. These apply to all projects under `<directory>`."

### Directory.Build.targets

Search for `Directory.Build.targets` the same way. These run **after** project evaluation and typically contain:
- Shared `<PackageReference>` items (e.g., analyzers applied to all projects)
- Conditional logic based on project type
- Custom MSBuild targets

Report: "Found Directory.Build.targets at `<path>`. Contains: [summarize content]."

### Multiple Directory.Build Files

If multiple `Directory.Build.props` files exist at different levels (e.g., root and `src/`), report the hierarchy:

```
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)
```

Note: Inner files do NOT automatically import outer files. Check for `<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />` to see if chaining is configured.

---

## Step 5: Detect Central Package Management (CPM)

### Directory.Packages.props

Search for `Directory.Packages.props` starting from the solution root and walking **upward** toward the repository root (or filesystem root). NuGet resolves CPM hierarchically -- a monorepo may have `Directory.Packages.props` in a parent directory that governs multiple solutions. Also check for `<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>` in any `Directory.Build.props` in the hierarchy, as CPM can be enabled there instead.

```xml
<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageV

Related in General