# C# Style Guide

This guide defines C# conventions for the gateway, worker, .NET client, test
CLIs, and C# tests.

## Baseline

- Use the latest stable C# version supported by the target runtime.
- Enable nullable reference types in new projects.
- Treat compiler warnings as actionable. Suppress only with a narrow reason.
- Prefer file-scoped namespaces.
- Prefer `sealed` classes unless inheritance is required.
- Keep public APIs explicit and small. Do not expose generated or transport
  internals through handwritten abstractions unless raw access is intentional.

## Source Documentation

- Maintain the existing documentation style in the file, project, and
  surrounding component.
- Write comments that include business-specific or domain-specific context when
  that context is available from the code, surrounding docs, or naming.
- Prefer XML documentation on public APIs when the behavior is not obvious from
  the signature.
- Avoid comments that restate syntax or control flow.

## Naming

- Use PascalCase for public types, methods, properties, events, and enum
  members.
- Use camelCase for local variables, parameters, and private fields.
- Prefix private fields with `_` only when that pattern is already established
  in the project.
- Use `Async` suffixes for methods that return `Task`, `Task<T>`,
  `ValueTask`, or `ValueTask<T>`.
- Keep names aligned with MXAccess terms: `MxStatusProxy`, `ServerHandle`,
  `ItemHandle`, `HResult`, and event family names should match the contract.

## Async And Cancellation

- Accept `CancellationToken` on public async methods that perform I/O or wait.
- Pass cancellation tokens through to called APIs.
- Do not use `Task.Run` to hide blocking COM calls. MXAccess calls belong on
  the worker STA.
- Use `ConfigureAwait(false)` in reusable libraries. It is optional in ASP.NET
  Core request handling where no synchronization context exists.
- Dispose async resources with `await using` when the type implements
  `IAsyncDisposable`.

## Errors

- Preserve protocol, gateway, worker, COM HRESULT, and MXAccess status details.
- Use typed exceptions at API boundaries, but prefer result DTOs when callers
  need method-specific MXAccess output.
- Do not log API keys, passwords, secured write values, or full tag values by
  default.
- Include correlation id and session id in diagnostics when available.

## Protobuf And Generated Code

- Do not hand-edit generated protobuf or gRPC files.
- Keep generated code in a clearly named `Generated` namespace or directory.
- Keep mapping code outside gRPC handlers so it can be unit tested.

## Formatting

- Run `dotnet format` when a solution or project is available.
- Use four spaces for indentation.
- Keep one public type per file unless a small nested type is clearer.
- Avoid region-heavy files. Split large responsibilities into focused types.

## Tests

- Use test names that describe behavior, condition, and result.
- Prefer fake workers, fake transports, or fake gRPC services over live
  MXAccess in unit tests.
- Mark live MXAccess tests as opt-in integration tests.
