# .NET Client Projects The .NET client workspace contains the MXAccess Gateway client library, test CLI, and unit tests. ## Projects | Project | Purpose | |---------|---------| | `MxGateway.Client` | .NET 10 library entry point, raw gRPC calls, and session helpers. | | `MxGateway.Client.Cli` | Test CLI for smoke and diagnostic commands. | | `MxGateway.Client.Tests` | Unit tests for client options, generated contract wiring, auth metadata, session helpers, cancellation, and event streaming. | The projects reference `src/MxGateway.Contracts/MxGateway.Contracts.csproj` so the client compiles against the same generated protobuf and gRPC types as the gateway. `clients/dotnet/generated` remains reserved for generator output if a future client build switches to client-local `Grpc.Tools` generation. ## Build And Test ```powershell dotnet build clients/dotnet/MxGateway.Client.sln dotnet test clients/dotnet/MxGateway.Client.sln --no-build ``` ## Client Usage `MxGatewayClient` opens a gRPC channel to the gateway and attaches the API key to every unary and streaming call as `authorization: Bearer `. Cancellation tokens passed to the public methods flow to the generated gRPC call. Client-side cancellation stops waiting for the gateway response; it does not abort an MXAccess COM call that is already executing inside a worker. ```csharp await using MxGatewayClient client = MxGatewayClient.Create( new MxGatewayClientOptions { Endpoint = new Uri("http://localhost:5000"), ApiKey = apiKey, }); MxGatewaySession session = await client.OpenSessionAsync(); try { int serverHandle = await session.RegisterAsync("sample-client"); int itemHandle = await session.AddItemAsync( serverHandle, "Area001.Pump001.Speed"); await session.AdviseAsync(serverHandle, itemHandle); } finally { await session.CloseAsync(); } ``` Use `OpenSessionRawAsync`, `CloseSessionRawAsync`, `InvokeAsync`, and `StreamEventsAsync` when tests or parity tools need direct generated protobuf messages. `MxGatewaySession.OpenSessionReply` keeps the raw session-open reply available, and command helpers have `*RawAsync` variants when callers need the complete `MxCommandReply`. `MxGatewaySession.CloseAsync` is explicit and idempotent. Repeated calls return the first `CloseSessionReply` instead of sending another close request.