--- 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 1. **Central package management** — Use `Directory.Packages.props` to manage NuGet package versions in one place. No version numbers in individual `.csproj` files. 2. **Shared build properties** — Use `Directory.Build.props` for common settings (target framework, nullable, implicit usings). Don't repeat in every project. 3. **.slnx for solutions** — The new XML-based solution format is cleaner and more merge-friendly than the legacy `.sln` format. 4. **src/tests separation** — Source projects in `src/`, test projects in `tests/`. 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 ```xml net10.0 14 enable enable true true ``` ### Directory.Packages.props (Central Package Management) ```xml true ``` ### Project File (.csproj) with Central Package Management ```xml ``` ### global.json (SDK Pinning) ```json { "sdk": { "version": "10.0.100", "rollForward": "latestFeature" } } ``` ### .slnx Solution Format ```xml ``` ### 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 ```xml ``` ### Don't Repeat Build Properties ```xml net10.0 enable enable ``` ### 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` |