# 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`, `ValueTask`, or `ValueTask`. - 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.