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