77 lines
3.0 KiB
Markdown
77 lines
3.0 KiB
Markdown
# 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.
|