project-structure

v2026.09.24

.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".

GitHub
安装命令
npx skhub add codewithmukesh/project-structure
Markdown
SKILL.md

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

<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

ElementConventionExample
SolutionCompanyName.AppName or AppNameMyApp.slnx
ProjectAppName.LayerMyApp.Api, MyApp.Domain
NamespaceMatches folder pathMyApp.Api.Features.Orders
Feature folderPascalCase, pluralFeatures/Orders/
Test projectProjectName.TestsMyApp.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

ScenarioRecommendation
New solution.slnx format
Package version managementDirectory.Packages.props (central)
Shared build settingsDirectory.Build.props
SDK version pinningglobal.json
Common using directivesGlobal 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 appModule-per-project with shared Contracts
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

MIT

源路径

skills/project-structure

默认分支

main

最新提交

2330089

Tree SHA

e9bdab0