Template
✨ Updates API, C#, Docker, MSBuild, and Testing guidelines
Refines conventions for ASP.NET API endpoints, C# documentation, Docker build arguments, MSBuild package management, and testing method naming and structure. These changes aim to enhance clarity and enforce best practices across the codebase.
This commit is contained in:
5 files changed
+21
-9
No files matched your search
@@ -10,11 +10,17 @@ description: "Use when writing API endpoints, routing, middleware, request/respo
|
||||
|
||||
## Endpoints
|
||||
|
||||
- Prefer **Minimal APIs**; use Controllers only when the added structure is justified.
|
||||
- Prefer **Minimal APIs**; use Controllers only when the endpoint group requires action filters, model binding customisation, or exceeds 10 endpoints sharing significant cross-cutting logic.
|
||||
- Group related endpoints using `MapGroup()` with a shared prefix and tag.
|
||||
- Use **typed results** (`TypedResults.Ok()`, `TypedResults.NotFound()`) over untyped `Results` for OpenAPI metadata inference.
|
||||
- Return **`ProblemDetails`** (RFC 9457) for all error responses — configure via `AddProblemDetails()`.
|
||||
|
||||
## Authorisation
|
||||
|
||||
- Apply `.RequireAuthorization()` at the group level for protected resources.
|
||||
- Reference policy names through `const string` fields on a shared static class (e.g., `.RequireAuthorization(AuthorizationPolicies.RequireAdminRole)`) instead of inline string literals.
|
||||
- Mark public endpoints explicitly with `.AllowAnonymous()`.
|
||||
|
||||
## Request Handling
|
||||
|
||||
- Bind request data with **`[AsParameters]`** for complex parameter sets.
|
||||
|
||||
@@ -8,11 +8,10 @@ Code style is enforced by `.editorconfig`, `.globalconfig`, and StyleCop analyze
|
||||
|
||||
## Non-Obvious Defaults
|
||||
|
||||
- XML doc comments required on public API in `src/` (suppressed in `tests/` and `samples/`).
|
||||
- XML doc comments required on all `public` and `protected` members in `src/` (suppressed in `tests/` and `samples/`).
|
||||
- Avoid `null!` (null-forgiving operator) — fix the nullability flow instead of suppressing the warning.
|
||||
|
||||
## Patterns
|
||||
|
||||
- Prefer **records** for DTOs, value objects, and other immutable data carriers.
|
||||
- Use `LoggerMessage`-generated `partial` methods on a `partial class` — never log inline (e.g., `logger.LogInformation(…)`).
|
||||
|
||||
- Use `LoggerMessage`-generated `partial` methods on a `partial class` — never log inline (e.g., `logger.LogInformation(…)`). If the containing type cannot be made `partial`, convert it to a `partial class` before adding logger methods. Do not fall back to inline logging.
|
||||
@@ -16,11 +16,11 @@ applyTo: "docker/**,compose*.yaml"
|
||||
|
||||
## Build Args
|
||||
|
||||
- `RUNTIME_BASE`: `web` (ASP.NET), `app` (console), or `self-contained`
|
||||
- `RUNTIME_BASE`: `web` (ASP.NET), `app` (console), or `self-contained`. If a use case does not match `web`, `app`, or `self-contained`, do not invent a new `RUNTIME_BASE` value — flag this to the user and ask which existing value best fits their scenario.
|
||||
- `CONFIGURATION`: `Release` (default) or `Debug`
|
||||
- `PUBLISHED_PROJECT`: Project name to publish (without path or extension)
|
||||
- `DATABASE_PROJECT`: EF Core project for migration bundles
|
||||
- `DBCONTEXT`: Optional DbContext name for migrations
|
||||
- `DBCONTEXT`: Optional DbContext name for migrations. If omitted, the migration bundle step must not pass `--context`; EF Core auto-discovers the single DbContext in `DATABASE_PROJECT`.
|
||||
|
||||
## Image Selection
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@ applyTo: "**/*.{csproj,props,targets}"
|
||||
|
||||
## Central Package Management
|
||||
|
||||
All package versions are declared in `Directory.Packages.props` at the repo root. In `.csproj` files:
|
||||
All package versions are declared in `Directory.Packages.props` at the repo root. In `Directory.Packages.props`, ensure the last child element of the root `<Project>` tag is `<Import Project="Directory.Packages.template.props" />`. `Directory.Packages.template.props` is **READ ONLY**, never edit it. The template provides default `<PackageVersion>` entries; any entry with the same `Include` declared earlier in `Directory.Packages.props` takes precedence over the template default, because MSBuild uses first-definition-wins semantics and the import appears last.
|
||||
|
||||
In `.csproj` files:
|
||||
|
||||
```xml
|
||||
<!-- Correct -->
|
||||
@@ -22,6 +24,8 @@ To add or update a version, edit `Directory.Packages.props`:
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
```
|
||||
|
||||
If the package does not exist in the template, simply add a new `<PackageVersion>` entry in `Directory.Packages.props`. No override logic is needed; the entry will be the sole definition.
|
||||
|
||||
## Properties Set Centrally (Do Not Override)
|
||||
|
||||
These are configured in the root `Directory.Build.props` — do **not** set them in individual projects:
|
||||
@@ -37,3 +41,5 @@ Handled automatically via `<InternalsVisibleToSuffix>` in the root props. Defaul
|
||||
<InternalsVisibleTo Include="MyProject.IntegrationTests" />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
This is in addition to the automatically generated entries; do not remove or duplicate the default suffix entries.
|
||||
@@ -15,9 +15,10 @@ Build configuration is handled by `tests/Directory.Build.props` — do not resta
|
||||
|
||||
- Test project: `<ProjectUnderTest>.Tests` (matches InternalsVisibleTo default).
|
||||
- Test classes: `<ClassUnderTest>Tests`.
|
||||
- Test methods: descriptive names — `MethodName_Condition_ExpectedResult` or similar.
|
||||
- Test methods: must use `MethodName_Condition_ExpectedResult` format. Example: `Add_NegativeNumbers_ThrowsArgumentException`.
|
||||
|
||||
## Structure
|
||||
|
||||
- Follow **Arrange / Act / Assert**.
|
||||
- Always propose a set of basic tests for new or changed code.
|
||||
- Always propose a set of basic tests for new or changed code. A basic test set must include at minimum: one happy-path test, one test per documented edge case or boundary condition, and one test for each expected exception.
|
||||
- If no edge cases are explicitly documented, use judgment to identify and cover the most likely boundary conditions (e.g. null inputs, empty collections, zero/max values) and note the assumption in a comment.
|
||||
Reference in new issue
Block a user