Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ Head over to [NATS documentation](https://docs.nats.io/nats-concepts/overview) f
- **NATS.Client.Services**: [Services](https://docs.nats.io/using-nats/developer/services)
- **NATS.Client.Simplified**: simplify common use cases especially for beginners
- **NATS.Client.Serializers.Json**: JSON serializer for ad-hoc types
- **NATS.Extensions.Microsoft.DependencyInjection**: extension to configure DI container
- **NATS.Client.Hosting**: DI integration for AOT-compatible and minimal-dependency scenarios
- **NATS.Extensions.Microsoft.DependencyInjection**: DI integration with ad-hoc JSON serialization enabled by default

## Contributing

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NATS.Net\NATS.Net.csproj" />
<ProjectReference Include="..\NATS.Client.Simplified\NATS.Client.Simplified.csproj" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/NATS.Net/NATS.Net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\NATS.Client.Core\NATS.Client.Core.csproj" />
<ProjectReference Include="..\NATS.Client.Hosting\NATS.Client.Hosting.csproj" />
<ProjectReference Include="..\NATS.Extensions.Microsoft.DependencyInjection\NATS.Extensions.Microsoft.DependencyInjection.csproj" />
<ProjectReference Include="..\NATS.Client.JetStream\NATS.Client.JetStream.csproj" />
<ProjectReference Include="..\NATS.Client.KeyValueStore\NATS.Client.KeyValueStore.csproj" />
<ProjectReference Include="..\NATS.Client.ObjectStore\NATS.Client.ObjectStore.csproj" />
Expand Down
7 changes: 7 additions & 0 deletions tools/site_src/documentation/advanced/aot.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ NuGet packages that are compatible with AOT publishing are:
- [NATS.Client.KeyValueStore](https://www.nuget.org/packages/NATS.Client.KeyValueStore)
- [NATS.Client.ObjectStore](https://www.nuget.org/packages/NATS.Client.ObjectStore)
- [NATS.Client.Services](https://www.nuget.org/packages/NATS.Client.Services)
- [NATS.Client.Hosting](https://www.nuget.org/packages/NATS.Client.Hosting) (for dependency injection)

> [!NOTE]
> For dependency injection in AOT scenarios, use `NATS.Client.Hosting` (with its `AddNats()` method)
> instead of `NATS.Extensions.Microsoft.DependencyInjection`. The latter depends on `NATS.Client.Simplified` which
> includes the ad hoc JSON serializer and is not AOT-compatible.
> See [Dependency Injection](dependency-injection.md) for a full comparison of the two DI packages.
194 changes: 194 additions & 0 deletions tools/site_src/documentation/advanced/dependency-injection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# Dependency Injection

NATS .NET provides two packages for integrating with Microsoft's dependency injection framework.
We acknowledge this can be confusing — they exist because they serve slightly different use cases,
particularly around serialization defaults and AOT compatibility.

## Which Package Should I Use?

| | `NATS.Extensions.Microsoft.DependencyInjection` | `NATS.Client.Hosting` |
|---|---|---|
| **Best for** | Most applications | AOT deployments, minimal dependencies |
| **Entry method** | `AddNatsClient()` | `AddNats()` |
| **API style** | Builder pattern (fluent) | Direct parameters |
| **JSON serialization** | Enabled by default (ad hoc) | Not included |
| **AOT compatible** | No | Yes |
| **Depends on** | `NATS.Client.Simplified` (includes Core + JSON serializer) | `NATS.Client.Core` only |
| **Included in `NATS.Net`** | Yes | Yes |

**In short:**
- Use **`NATS.Extensions.Microsoft.DependencyInjection`** if you want things to "just work" with JSON serialization
out of the box and you don't need AOT publishing.
- Use **`NATS.Client.Hosting`** if you need AOT compatibility, want minimal dependencies,
or prefer to configure serialization yourself.

## NATS.Extensions.Microsoft.DependencyInjection

Install the package:

```shell
dotnet add package NATS.Extensions.Microsoft.DependencyInjection
```

This package provides `AddNatsClient()` with a builder pattern for configuration.
It is included in the `NATS.Net` meta-package, but can also be installed standalone.
It brings in the ad hoc JSON serializer (`NATS.Client.Serializers.Json` via `NATS.Client.Simplified`),
so you can publish and subscribe with data classes using JSON serialization without any extra setup.

### Basic Usage

```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddNatsClient();
```

This registers `INatsConnection`, `NatsConnection`, and `INatsClient` in the DI container.

### Configuration

```csharp
builder.Services.AddNatsClient(nats =>
{
nats.ConfigureOptions(opts =>
opts.Configure(o => o.Opts = o.Opts with { Url = "nats://myserver:4222" }));
});
```

You can also configure the connection after it's created:

```csharp
builder.Services.AddNatsClient(nats =>
{
nats.ConfigureConnection((provider, connection) =>
{
// Access DI services and configure the connection
});
});
```

### Keyed Services (.NET 8+)

Register multiple NATS connections with different keys:

```csharp
builder.Services.AddNatsClient(nats =>
{
nats.WithKey("primary");
nats.ConfigureOptions(opts =>
opts.Configure(o => o.Opts = o.Opts with { Url = "nats://primary:4222" }));
});

builder.Services.AddNatsClient(nats =>
{
nats.WithKey("secondary");
nats.ConfigureOptions(opts =>
opts.Configure(o => o.Opts = o.Opts with { Url = "nats://secondary:4222" }));
});
```

Inject with `[FromKeyedServices]`:

```csharp
public class MyService([FromKeyedServices("primary")] INatsConnection primaryNats)
{
}
```

> [!NOTE]
> `WithKey()` must be called before `ConfigureOptions()` or other configuration methods.

## NATS.Client.Hosting

Install the package:

```shell
dotnet add package NATS.Client.Hosting
```

This package provides `AddNats()` with a simpler callback-based API.
It depends only on `NATS.Client.Core`, so it doesn't bring in the JSON serializer
or any other higher-level client packages. This makes it suitable for
[AOT deployments](aot.md) and scenarios where you want to control your dependency footprint.

### Basic Usage

```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddNats();
```

This registers `INatsConnection` and `NatsConnection` in the DI container.

### Configuration

```csharp
builder.Services.AddNats(
configureOpts: opts => opts with { Url = "nats://myserver:4222" },
configureConnection: conn =>
{
// Configure the connection after creation
});
```

### Keyed Services (.NET 8+)

```csharp
builder.Services.AddNats(key: "primary", configureOpts: opts => opts with { Url = "nats://primary:4222" });
builder.Services.AddNats(key: "secondary", configureOpts: opts => opts with { Url = "nats://secondary:4222" });
```

### Serialization

Since `NATS.Client.Hosting` does not include a JSON serializer, you need to set up serialization yourself
if you need to work with data types beyond the built-in `int`, `string`, and `byte[]` support.
See [Serialization](serialization.md) for details on configuring custom serializers,
and [AOT Deployments](aot.md) for AOT-specific guidance.

```csharp
builder.Services.AddNats(configureOpts: opts => opts with
{
SerializerRegistry = new MyCustomSerializerRegistry(),
});
```

## Key Differences in Detail

### Serialization Defaults

`NATS.Extensions.Microsoft.DependencyInjection` automatically configures `NatsClientDefaultSerializerRegistry`,
which supports ad hoc JSON serialization using `System.Text.Json`. This means you can immediately
publish and subscribe with your own data classes:

```csharp
// Works out of the box with NATS.Extensions.Microsoft.DependencyInjection
await connection.PublishAsync("orders", new Order { Id = 1, Item = "Widget" });
```

`NATS.Client.Hosting` uses the default `NatsOpts` serializer registry, which only supports
`int`, `string`, `byte[]`, and other primitive types. For anything else, you must configure
a serializer.

### Channel Full Mode

`NATS.Extensions.Microsoft.DependencyInjection` sets `SubPendingChannelFullMode` to
`BoundedChannelFullMode.Wait` by default (matching `NatsClient` behavior). This means
a slow subscriber will apply backpressure instead of dropping messages.

`NATS.Client.Hosting` uses the `NatsOpts` default of `BoundedChannelFullMode.DropNewest`,
which drops the newest messages when the subscriber's channel is full.

### Options Pattern

`NATS.Extensions.Microsoft.DependencyInjection` uses the Microsoft Options pattern
(`IOptionsMonitor<T>`) under the hood, providing better integration with the configuration
system and support for named options.

`NATS.Client.Hosting` uses simple `Func<NatsOpts, NatsOpts>` callbacks for configuration.

## What's Next

- [Serialization](serialization.md) for configuring custom serializers.
- [AOT Deployments](aot.md) for native ahead-of-time publishing guidance.
- [Platform Compatibility](platform-compatibility.md) for API differences across target frameworks.
1 change: 1 addition & 0 deletions tools/site_src/documentation/advanced/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ essentially sent back to back after they're picked up from internal queues and b

## What's Next

- [Dependency Injection](dependency-injection.md) explains the two DI packages (`NATS.Client.Hosting` and `NATS.Extensions.Microsoft.DependencyInjection`) and when to use each one.
- [Slow Consumers](slow-consumers.md) explains how to detect and handle subscribers that can't keep up with the message rate, including the `MessageDropped` and `SlowConsumerDetected` events.
- [Serialization](serialization.md) is the process of converting an object into a format that can be stored or transmitted.
- [Security](security.md) is an important aspect of any distributed system. NATS provides a number of security features to help you secure your applications.
Expand Down
2 changes: 2 additions & 0 deletions tools/site_src/documentation/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
- name: Advanced Options
href: advanced/intro.md
items:
- name: Dependency Injection
href: advanced/dependency-injection.md
- name: Slow Consumers
href: advanced/slow-consumers.md
- name: Serialization
Expand Down
Loading