NATS: Aspire.NATS.Net 库
NuGet
快速入门
首先,你需要已经配置了 NATS 服务器,并且知道访问这个服务器的 URL 地址。
安装 NuGet
使用你熟悉的方式安装 NuGet 库
dotnet add package Aspire.NATS.Net
使用示例
在项目的 Program.cs 中,调用 AddNatsClient()
扩展方法以在依赖注入容器中注册 INatsConnection
对象。该方法需要一个连接串作为参数。
builder.AddNatsClient("nats");
以后可以在通过 INatsConnection
来注入对象实例。例如,在 Web API 的控制器中
private readonly INatsConnection _connection;
public ProductsController(INatsConnection connection)
{
_connection = connection;
}
配置
基于你的需求和项目的使用方式,.NET Aspire NATS 组件提供了多种方式配置 NATS 连接。
使用连接串
当使用来自 ConnectionStrings 配置节中的连接串时,可以在调用 AddNatsClient() 方法的时候,提供连接串的名称。
builder.AddNatsClient("myConnection");
其中的连接串来自配置文件 appsettings.json
{
"ConnectionStrings": {
"myConnection": "nats://nats:4222"
}
}
使用配置提供器
.NET Aspire NATS 组件支持 Microsoft.Extensions.Configuration,它会从键 Aspire:Nats:Client
中加载 NatsClientSettings
配置。例如下面的 appsettings.json 中
{
"Aspire": {
"Nats": {
"Client": {
"DisableHealthChecks": true
}
}
}
}
使用内联代码
你还可以通过提供 Action<NatsClientSettings> configureSettings
委托来内联配置其它设置,例如,禁用健康检查:
builder.AddNatsClient("nats", settings => settings.DisableHealthChecks = true);
AppHost 扩展
在 AppHost 项目中,安装 Aspire.Hosting.Nats NuGet 库
dotnet add package Aspire.Hosting.Nats
然后,在 AppHost 的 Program.cs 中,注册 NATS 服务器并使用它。
// nats, the "nats" is the name of connection string
// MUST call the WithJetStream() if it is requried
var nats = builder.AddNats("nats")
.WithJetStream();
var myService = builder.AddProject<Projects.MyService>()
.WithReference(nats);
这里的 WithReference() 方法,配置了 MyService 项目中名为 "nats" 的连接。请注意,在 MyService 项目的 Program.cs 中,使用如下方式来使用该连接。
builder.AddNatsClient("nats");
实现代码
注册用于连接到 NATS 服务器的 NATS 客户端的 INatsConnection 服务
- connectionName,用于从 ConnectionStrings 配置节中提取 NATS 连接串的名称
- configureSettings,用于定制 NatsClientSettings 配置项
- configureOptions,用于定制 NatsOpts
public static void AddNatsClient(this IHostApplicationBuilder builder, string connectionName, Action<NatsClientSettings>? configureSettings = null, Func<NatsOpts, NatsOpts>? configureOptions = null)
=> AddNatsClient(builder, configurationSectionName: DefaultConfigSectionName, connectionName: connectionName, serviceKey: null, configureSettings: configureSettings, configureOptions: configureOptions);
private static void AddNatsClient(this IHostApplicationBuilder builder, string configurationSectionName, string connectionName, object? serviceKey, Action<NatsClientSettings>? configureSettings, Func<NatsOpts, NatsOpts>? configureOptions)
{
ArgumentNullException.ThrowIfNull(builder);
NatsClientSettings settings = new();
builder.Configuration.GetSection(configurationSectionName).Bind(settings);
if (builder.Configuration.GetConnectionString(connectionName) is string connectionString)
{
settings.ConnectionString = connectionString;
}
configureSettings?.Invoke(settings);
NatsConnection Factory(IServiceProvider provider)
{
var options = NatsOpts.Default with
{
LoggerFactory = provider.GetRequiredService<ILoggerFactory>(),
};
if (configureOptions != null)
{
options = configureOptions(options);
}
if (settings.ConnectionString == null)
{
throw new InvalidOperationException($"NATS connection string not found: {connectionName}");
}
options = options with { Url = settings.ConnectionString };
return new NatsConnection(options);
}
if (serviceKey == null)
{
builder.Services.TryAddSingleton(Factory);
builder.Services.TryAddSingleton<INatsConnection>(static provider => provider.GetRequiredService<NatsConnection>());
}
else
{
builder.Services.TryAddKeyedSingleton<NatsConnection>(serviceKey, (provider, _) => Factory(provider));
builder.Services.TryAddKeyedSingleton<INatsConnection>(serviceKey, static (provider, key) => provider.GetRequiredKeyedService<NatsConnection>(key));
}
if (!settings.DisableHealthChecks)
{
builder.TryAddHealthCheck(new HealthCheckRegistration(
serviceKey is null ? "NATS" : $"NATS_{connectionName}",
sp => new NatsHealthCheck(serviceKey is null
? sp.GetRequiredService<INatsConnection>()
: sp.GetRequiredKeyedService<INatsConnection>(serviceKey)),
failureStatus: default,
tags: default,
timeout: default));
}
if (!settings.DisableTracing)
{
builder.Services
.AddOpenTelemetry()
.WithTracing(tracer =>
{
tracer.AddSource(ActivityNameSource);
});
}
}
/// <summary>
/// Registers <see cref="INatsJSContext"/> service for NATS JetStream operations.
/// </summary>
/// <param name="builder">The <see cref="IHostApplicationBuilder" /> to read config from and add services to.</param>
/// <exception cref="ArgumentNullException">Thrown if mandatory <paramref name="builder"/> is null.</exception>
public static void AddNatsJetStream(this IHostApplicationBuilder builder)
{
ArgumentNullException.ThrowIfNull(builder);
builder.Services.AddSingleton<INatsJSContext>(static provider =>
{
return new NatsJSContextFactory().CreateContext(provider.GetRequiredService<INatsConnection>());
});
}