|
| 1 | +# Copilot Instructions for ASP.NET API Versioning |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This is **ASP.NET API Versioning** (`dotnet/aspnet-api-versioning`), a .NET Foundation library providing API versioning semantics for ASP.NET. It produces multiple NuGet packages supporting ASP.NET Core (Minimal APIs, MVC, OData) and legacy ASP.NET Web API. |
| 6 | + |
| 7 | +## Build & Test |
| 8 | + |
| 9 | +- **SDK**: .NET 10.0 (`net10.0` primary; `net472` for legacy Web API; `netstandard1.0`/`2.0` for Abstractions) |
| 10 | +- **Solution**: `asp.slnx` at repo root |
| 11 | +- **Restore**: `dotnet restore` |
| 12 | +- **Build**: `dotnet build` (or `dotnet build --configuration Release`) |
| 13 | +- **Test**: `dotnet test` (or `dotnet test --configuration Release`) |
| 14 | +- **Pack**: `dotnet pack --configuration Release` |
| 15 | +- **Test runner**: Microsoft.Testing.Platform with xUnit v3 (`xunit.v3.mtp-v2`) |
| 16 | + |
| 17 | +## Architecture |
| 18 | + |
| 19 | +``` |
| 20 | +src/ |
| 21 | +├── Abstractions/ # Core types (ApiVersion, etc.) — multi-target netstandard1.0+ |
| 22 | +├── AspNetCore/ |
| 23 | +│ ├── WebApi/ # Asp.Versioning.Http, .Mvc, .Mvc.ApiExplorer, .OpenApi |
| 24 | +│ ├── OData/ # Asp.Versioning.OData, .OData.ApiExplorer |
| 25 | +│ └── Acceptance/ # Integration tests using TestHost |
| 26 | +├── AspNet/ |
| 27 | +│ ├── WebApi/ # Asp.Versioning.WebApi, .WebApi.ApiExplorer (legacy) |
| 28 | +│ ├── OData/ # Asp.Versioning.WebApi.OData (legacy) |
| 29 | +│ └── Acceptance/ # Integration tests |
| 30 | +├── Client/ # Asp.Versioning.Http.Client |
| 31 | +└── Common/ |
| 32 | + ├── src/ # Shared code via .shproj (Common, Common.Mvc, Common.OData, etc.) |
| 33 | + └── test/ # Tests for shared code |
| 34 | +examples/ # Working example apps for each flavor |
| 35 | +build/ # MSBuild props/targets, CI YAML, signing key |
| 36 | +``` |
| 37 | + |
| 38 | +- **Shared projects** (`.shproj`) under `src/Common/src/` contain code compiled into multiple assemblies. When modifying shared code, consider impact on all consuming projects. |
| 39 | +- Production code lives in `src/**/src/`; tests live in `src/**/test/`. |
| 40 | + |
| 41 | +## Code Conventions |
| 42 | + |
| 43 | +- **C# Latest** language version with **implicit usings** enabled |
| 44 | +- **Nullable reference types**: enabled in production code, disabled in tests |
| 45 | +- **`var`**: preferred everywhere |
| 46 | +- **`this.`**: avoid unless necessary (enforced as error) |
| 47 | +- **Predefined type names**: use `int`, `string` over `Int32`, `String` (enforced as error) |
| 48 | +- **Braces**: Allman style (new line before all braces) |
| 49 | +- **Indentation**: 4 spaces for C#; 1 space for XML/MSBuild files |
| 50 | +- **Line length**: 120 characters guideline |
| 51 | +- **Properties**: expression-bodied preferred |
| 52 | +- **Methods**: block body (not expression-bodied) |
| 53 | +- **Analyzers**: StyleCop v1.2.0-beta with `TreatWarningsAsErrors: true` — fix all warnings before committing |
| 54 | +- **Strong naming**: all production assemblies are signed (`build/key.snk`) |
| 55 | +- **CLS Compliance**: production assemblies are CLS-compliant |
| 56 | + |
| 57 | +## Test Conventions |
| 58 | + |
| 59 | +- **Framework**: xUnit v3 with FluentAssertions and Moq |
| 60 | +- **Class naming**: `[ClassName]Test` (e.g., `ApiVersionTest`, `SunsetPolicyManagerTest`) |
| 61 | +- **Method structure**: arrange / act / assert (use comments to delineate sections) |
| 62 | +- **Async tests**: use `TestContext.Current.CancellationToken` |
| 63 | +- **Assertions**: FluentAssertions (`.Should().Be()`, `.Should().BeEquivalentTo()`, etc.) |
| 64 | +- **Mocking**: Moq (`Mock.Of<>()`, `Mock.Get().Verify()`) |
| 65 | +- **Every bug fix or feature must include tests** |
| 66 | +- **Acceptance tests** use `TestHost` for full integration scenarios |
| 67 | + |
| 68 | +## Build Infrastructure |
| 69 | + |
| 70 | +- MSBuild property hierarchy flows through `build/*.props` → `src/Directory.Build.props` → individual `.csproj` |
| 71 | +- NuGet package metadata is centralized in `build/nuget.props` |
| 72 | +- Version is set per-project in `.csproj` files (currently `10.0.0`) |
| 73 | +- CI runs on Azure Pipelines (`azure-pipelines.yml` → `build/steps-ci.yml`) |
| 74 | +- Deterministic builds are enabled in CI (`ContinuousIntegrationBuild=true`) |
| 75 | +- SourceLink is configured for GitHub |
| 76 | + |
| 77 | +## Common Pitfalls |
| 78 | + |
| 79 | +- Modifying `.shproj` shared projects affects multiple target assemblies — always build the full solution to verify |
| 80 | +- The `.editorconfig` and StyleCop analyzers enforce strict style; the build fails on violations |
| 81 | +- Legacy ASP.NET Web API projects (`net472`) have different API surfaces — test both frameworks when changing shared code |
| 82 | +- Example projects have their own `Directory.Build.props` and `Directory.Packages.props` separate from `src/` |
0 commit comments