project-structure
.NET solution and project structure conventions. Covers .slnx format, Directory.Build.props, Directory.Packages.props for central package management, global usings, and naming conventions. Load this skill when setting up a new solution, adding projects, configuring build properties, or when the user mentions "solution structure", ".slnx", "Directory.Build.props", "central package management", "Directory.Packages.props", "global usings", ".editorconfig", "project layout", or "naming conventions".
How do I install this agent skill?
npx skills add https://github.com/codewithmukesh/dotnet-claude-kit --skill project-structureIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill provides architectural guidance and templates for .NET project organization. It does not contain any executable scripts, remote downloads, or sensitive data access patterns.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
- ZeroLeakspass
Score: 93/100 · 2 sections analyzed
What does this agent skill do?
Project Structure
Core Principles
- Central package management — Use
Directory.Packages.propsto manage NuGet package versions in one place. No version numbers in individual.csprojfiles. - Shared build properties — Use
Directory.Build.propsfor common settings (target framework, nullable, implicit usings). Don't repeat in every project. - .slnx for solutions — The new XML-based solution format is cleaner and more merge-friendly than the legacy
.slnformat. - src/tests separation — Source projects in
src/, test projects intests/. Clear boundary.
Patterns
Solution Layout
MyApp/
├── MyApp.slnx # Solution file
├── Directory.Build.props # Shared MSBuild properties
├── Directory.Packages.props # Central package management
├── .editorconfig # Code style rules
├── .gitignore
├── global.json # SDK version pinning
├── src/
│ ├── MyApp.Api/ # Web API (entry point)
│ │ ├── MyApp.Api.csproj
│ │ ├── Program.cs
│ │ └── Features/
│ ├── MyApp.Domain/ # Domain entities, value objects (optional)
│ │ └── MyApp.Domain.csproj
│ └── MyApp.Infrastructure/ # EF Core, external services (optional)
│ └── MyApp.Infrastructure.csproj
└── tests/
└── MyApp.Api.Tests/
└── MyApp.Api.Tests.csproj
Directory.Build.props
<Project>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>14</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
</Project>
Directory.Packages.props (Central Package Management)
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<!-- Versions below are illustrative — resolve the current stable versions
with `dotnet add package <name>` (no --version flag); see the packages rule -->
<!-- ASP.NET Core -->
<PackageVersion Include="Mediator.Abstractions" Version="3.0.0" />
<PackageVersion Include="Mediator.SourceGenerator" Version="3.0.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
<!-- Data -->
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.10" />
<!-- Observability -->
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
<!-- Testing -->
<PackageVersion Include="xunit.v3" Version="3.2.2" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.10" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.13.0" />
</ItemGroup>
</Project>
Project File (.csproj) with Central Package Management
<Project Sdk="Microsoft.NET.Sdk.Web">
<!-- No TargetFramework here — inherited from Directory.Build.props -->
<ItemGroup>
<!-- No Version attribute — managed centrally -->
<PackageReference Include="Mediator.Abstractions" />
<PackageReference Include="Mediator.SourceGenerator" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" />
<PackageReference Include="Microsoft.EntityFrameworkCore" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<PackageReference Include="Serilog.AspNetCore" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyApp.Domain\MyApp.Domain.csproj" />
<ProjectReference Include="..\MyApp.Infrastructure\MyApp.Infrastructure.csproj" />
</ItemGroup>
</Project>
global.json (SDK Pinning)
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
.slnx Solution Format
<Solution>
<Folder Name="/src/">
<Project Path="src/MyApp.Api/MyApp.Api.csproj" />
<Project Path="src/MyApp.Domain/MyApp.Domain.csproj" />
<Project Path="src/MyApp.Infrastructure/MyApp.Infrastructure.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/MyApp.Api.Tests/MyApp.Api.Tests.csproj" />
</Folder>
</Solution>
Naming Conventions
| Element | Convention | Example |
|---|---|---|
| Solution | CompanyName.AppName or AppName | MyApp.slnx |
| Project | AppName.Layer | MyApp.Api, MyApp.Domain |
| Namespace | Matches folder path | MyApp.Api.Features.Orders |
| Feature folder | PascalCase, plural | Features/Orders/ |
| Test project | ProjectName.Tests | MyApp.Api.Tests |
Anti-patterns
Don't Scatter Package Versions
<!-- BAD — version in every .csproj, version drift -->
<PackageReference Include="Mediator.Abstractions" Version="2.0.0" /> <!-- in Project A -->
<PackageReference Include="Mediator.Abstractions" Version="3.0.0" /> <!-- in Project B -->
<!-- GOOD — central management, one version -->
<!-- Directory.Packages.props: <PackageVersion Include="Mediator.Abstractions" Version="3.0.0" /> -->
<!-- .csproj: <PackageReference Include="Mediator.Abstractions" /> -->
Don't Repeat Build Properties
<!-- BAD — same properties in every .csproj -->
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<!-- GOOD — once in Directory.Build.props, inherited everywhere -->
Don't Mix Source and Test Projects
# BAD — tests mixed with source
src/
MyApp.Api/
MyApp.Api.Tests/ # test project in src/
# GOOD — clear separation
src/
MyApp.Api/
tests/
MyApp.Api.Tests/
Decision Guide
| Scenario | Recommendation |
|---|---|
| New solution | .slnx format |
| Package version management | Directory.Packages.props (central) |
| Shared build settings | Directory.Build.props |
| SDK version pinning | global.json |
| Common using directives | Global usings in Directory.Build.props |
| Small API (1-2 devs) | Single project (MyApp.Api) |
| Medium API (3-5 devs) | 2-3 projects (Api, Domain, Infrastructure) |
| Large / modular app | Module-per-project with shared Contracts |
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/codewithmukesh/dotnet-claude-kit/project-structure">View project-structure on skillZs</a>