关于 project-structure
project-structure 是用于组织 .NET 解决方案和项目的技能,介绍相关结构约定。内容涵盖共享构建设置、集中管理 NuGet 版本、分离源代码与测试,以及命名规范。
主要功能
- 01集中管理 NuGet 包版本
- 02共享 MSBuild 属性
- 03.slnx 解决方案格式建议
- 04分离 src/ 与 tests/ 目录
- 05项目和命名空间命名规范
- 06使用 global.json 固定 SDK 版本
适用场景
- 01规划新的 .NET 解决方案
- 02集中管理包版本
- 03统一多个项目的构建设置
- 04分离源代码项目与测试项目
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ codewithmukesh/ dotnet-claude-kit --skill project-structure安装后在 Claude Code 中输入/project-structure确认已加载。
详细介绍
项目结构
核心原则
- 集中管理包 — 使用
Directory.Packages.props在一个位置管理 NuGet 包版本。各个.csproj文件中不写版本号。 - 共享构建属性 — 使用
Directory.Build.props配置通用设置(目标框架、可空性、隐式 using)。无需在每个项目中重复设置。 - 解决方案使用 .slnx — 新的基于 XML 的解决方案格式比旧版
.sln格式更简洁,也更便于合并。 - 分离 src/tests — 源代码项目放在
src/中,测试项目放在tests/中。边界清晰。
模式
解决方案布局
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(集中管理包)
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Mediator.Abstractions" Version="3.0.0" />
<PackageVersion Include="Mediator.SourceGenerator" Version="3.0.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.10" />
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
<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>
使用集中包管理的项目文件(.csproj)
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<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 版本固定)
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
.slnx 解决方案格式
<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>
命名约定
| 元素 | 约定 | 示例 |
|---|---|---|
| 解决方案 | CompanyName.AppName 或 AppName | MyApp.slnx |
| 项目 | AppName.Layer | MyApp.Api、MyApp.Domain |
| 命名空间 | 与文件夹路径一致 | MyApp.Api.Features.Orders |
| 功能文件夹 | PascalCase,使用复数形式 | Features/Orders/ |
| 测试项目 | ProjectName.Tests | MyApp.Api.Tests |
反模式
不要分散管理包版本
<PackageReference Include="Mediator.Abstractions" Version="2.0.0" />
<PackageReference Include="Mediator.Abstractions" Version="3.0.0" />
不要重复构建属性
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
不要混合源代码项目和测试项目
# 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/
决策指南
| 场景 | 建议 |
|---|---|
| 新建解决方案 | 使用 .slnx 格式 |
| 包版本管理 | 使用 Directory.Packages.props(集中管理) |
| 共享构建设置 | 使用 Directory.Build.props |
| 固定 SDK 版本 | 使用 global.json |
| 通用 using 指令 | 在 Directory.Build.props 中使用全局 using |
| 小型 API(1-2 名开发者) | 单个项目(MyApp.Api) |
| 中型 API(3-5 名开发者) | 2-3 个项目(Api、Domain、Infrastructure) |
| 大型/模块化应用 | 每个模块一个项目,并共享 Contracts |
评论
支持 Markdown