# Setup This guide covers prerequisites, building, running, and testing the NATS .NET server. ## Prerequisites ### .NET 10 SDK The project targets `net10.0` with `LangVersion preview` (configured in `Directory.Build.props`). Install the .NET 10 preview SDK from https://dotnet.microsoft.com/download. Verify your installation: ```bash dotnet --version # Expected: 10.0.x ``` ### Go Toolchain (optional) The Go toolchain is only needed if you want to run the reference server from `golang/nats-server/` or execute Go test suites for cross-validation. It is not required for building or testing the .NET port. ```bash go version # Expected: go1.22 or later ``` --- ## Building The solution file uses the `.slnx` format (not `.sln`). Pass it explicitly if your tooling requires it. ```bash # Build all projects dotnet build # Clean and rebuild dotnet clean && dotnet build ``` The solution contains three projects: | Project | Path | |---------|------| | `NATS.Server` | `src/NATS.Server/` | | `NATS.Server.Host` | `src/NATS.Server.Host/` | | `NATS.Server.Tests` | `tests/NATS.Server.Tests/` | All projects share settings from `Directory.Build.props`: `net10.0` target framework, nullable reference types enabled, warnings treated as errors. --- ## Running The server executable is `NATS.Server.Host`. With no arguments it binds to `0.0.0.0:4222`. ```bash dotnet run --project src/NATS.Server.Host ``` ### CLI Arguments | Flag | Alias | Type | Default | Description | |------|-------|------|---------|-------------| | `-p` | `--port` | `int` | `4222` | TCP port to listen on | | `-a` | `--addr` | `string` | `0.0.0.0` | Bind address | | `-n` | `--name` | `string` | `nats-dotnet-` | Server name reported in INFO | ```bash # Custom port dotnet run --project src/NATS.Server.Host -- -p 14222 # Custom address and name dotnet run --project src/NATS.Server.Host -- -a 127.0.0.1 -p 4222 -n dev-server ``` The `--` separator is required to pass arguments through `dotnet run` to the application. Startup log output (Serilog console sink): ``` [12:00:00 INF] Listening on 0.0.0.0:4222 ``` --- ## Testing ```bash # Run all tests dotnet test # Run tests with verbose output dotnet test -v normal # Run a single test project dotnet test tests/NATS.Server.Tests # Run a specific test by name dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~SubListTests" ``` ### Test Stack | Package | Version | Purpose | |---------|---------|---------| | `xunit` | 2.9.3 | Test framework | | `xunit.runner.visualstudio` | 3.1.4 | VS/Rider test runner integration | | `Shouldly` | 4.3.0 | Assertion library | | `NSubstitute` | 5.3.0 | Mocking | | `NATS.Client.Core` | 2.7.2 | Official NATS .NET client for integration tests | | `coverlet.collector` | 6.0.4 | Code coverage | Do not use FluentAssertions or Moq — the project uses Shouldly and NSubstitute exclusively. ### Test Files | File | Covers | |------|--------| | `ParserTests.cs` | `NatsParser.TryParse` for each command type | | `SubjectMatchTests.cs` | `SubjectMatch` validation and wildcard matching | | `SubListTests.cs` | `SubList` trie insert, remove, match, and cache behaviour | | `ClientTests.cs` | `NatsClient` command dispatch and subscription tracking | | `ServerTests.cs` | `NatsServer` pub/sub, wildcards, queue groups | | `IntegrationTests.cs` | End-to-end tests using `NATS.Client.Core` against a live server | --- ## NuGet: Central Package Management Package versions are defined centrally in `Directory.Packages.props`. Individual `.csproj` files reference packages without a `Version` attribute: ```xml ``` ```xml ``` To add a new dependency: add a `` entry in `Directory.Packages.props`, then add a `` (without `Version`) in the relevant `.csproj`. --- ## Logging The host configures Serilog via `Microsoft.Extensions.Logging` in `Program.cs`: ```csharp Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .Enrich.FromLogContext() .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") .CreateLogger(); using var loggerFactory = new Serilog.Extensions.Logging.SerilogLoggerFactory(Log.Logger); var server = new NatsServer(options, loggerFactory); ``` `NatsServer` and `NatsClient` receive `ILoggerFactory` and `ILogger` respectively via constructor injection. The core library (`NATS.Server`) depends only on `Microsoft.Extensions.Logging.Abstractions` — it has no direct Serilog dependency. The Serilog packages are wired in `NATS.Server.Host`. Per-client loggers are created with a scoped category name that includes the client ID: ```csharp var clientLogger = _loggerFactory.CreateLogger($"NATS.Server.NatsClient[{clientId}]"); ``` To adjust log levels at runtime, modify the `LoggerConfiguration` in `Program.cs`. --- ## Related Documentation - [Architecture](./Architecture.md) - [Configuration Overview](../Configuration/Overview.md) - [Protocol Overview](../Protocol/Overview.md) - [Server Overview](../Server/Overview.md)