project-structure
codewithmukesh/dotnet-claude-kit
Organize .NET solutions with central package management, shared build properties, and modern conventions.
What is project-structure?
Establishes best practices for .NET solution structure using .slnx format, Directory.Build.props for shared settings, and Directory.Packages.props for centralized package versioning. Use this when setting up new solutions, configuring build properties, or organizing multi-project applications.
- Central package version management via Directory.Packages.props to eliminate version drift
- Shared build properties (target framework, nullable, implicit usings) in Directory.Build.props inherited by all projects
- Modern .slnx XML-based solution format that is merge-friendly and cleaner than legacy .sln
- Clear src/tests directory separation with consistent naming conventions (AppName.Layer, AppName.Tests)
- SDK version pinning via global.json and code style enforcement with .editorconfig
- Feature-folder organization patterns and anti-pattern guidance for avoiding common structural mistakes
How to install project-structure
npx skills add https://github.com/codewithmukesh/dotnet-claude-kit --skill project-structureHow to use project-structure
- 1.Create the root solution file (MyApp.slnx) and organize projects into src/ and tests/ folders
- 2.Add Directory.Build.props at the solution root with shared PropertyGroup settings (TargetFramework, LangVersion, Nullable, ImplicitUsings)
- 3.Create Directory.Packages.props with ManagePackageVersionsCentrally enabled and list all package versions centrally
- 4.Update individual .csproj files to reference packages without Version attributes, relying on central management
- 5.Add global.json at the solution root to pin the .NET SDK version
- 6.Apply naming conventions: solutions as CompanyName.AppName, projects as AppName.Layer, namespaces matching folder paths
Use cases
- Setting up a new .NET solution with multiple projects (API, Domain, Infrastructure layers)
- Migrating from scattered package versions to centralized management across existing projects
- Establishing consistent build properties and C# language settings across a team
- Organizing feature-based folder structures within layered projects
- Pinning SDK versions and enforcing code style rules across a development team
- Backend developers building multi-project .NET applications
- Teams establishing or refactoring solution structure and conventions
- Architects designing layered or modular .NET systems
- DevOps/build engineers standardizing build configuration across projects
project-structure FAQ
Central management prevents version drift (different projects using different versions of the same package), makes updates easier, and provides a single source of truth for dependencies across the entire solution.
Use .slnx for new solutions; it is the modern XML-based format that is cleaner, more merge-friendly, and better supported in current tooling.
Directory.Build.props holds shared settings (TargetFramework, LangVersion, Nullable, ImplicitUsings, compiler warnings). Individual .csproj files list only project-specific PackageReferences and ProjectReferences.
Use 2–3 projects: MyApp.Api (entry point, controllers), MyApp.Domain (entities, value objects), and MyApp.Infrastructure (EF Core, external services). Place them in src/ and tests in a separate tests/ folder.
It pins the .NET SDK version for the solution, ensuring all developers and CI/CD use the same SDK version and preventing unexpected behavior from SDK upgrades.
Full instructions (SKILL.md)
Source of truth, from codewithmukesh/dotnet-claude-kit.
name: project-structure description: > .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".
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 |
Related skills
More from codewithmukesh/dotnet-claude-kit and the wider catalog.

resilience
Resilience patterns for .NET 10 using Polly v8: retry, circuit breaker, timeout, fallback, and hedging.

scaffold
Architecture-aware feature scaffolding for .NET 10 projects with complete layer generation.

scalar
Modern API documentation UI for .NET 10, replacing Swagger with faster rendering and built-in dark mode.

security-scan
Deep static security scan for .NET apps across 6 layers: packages, secrets, OWASP patterns, auth, CORS, and data protection.

serilog
Structured logging for .NET 10 with configuration, enrichers, sinks, and request logging.

spec
Turn vague ideas into agreed, persisted specifications through relentless structured questioning.