-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update NATS.Client.Hosting package as NATS.Extensions.Microsoft.Depen…
…dencyInjection (#433) * Added NATS.Extensions.Microsoft.DependencyInjection project. Added NatsBuilder for customization of NATS configuration. * dotnet format * Marked AddNats method as obsolete and suggested to use NATS.Extensions.Microsoft.DependencyInjection instead. * post-rebase clean up * rename hosting method * Test fix * Project refs --------- Co-authored-by: Ziya Suzen <ziya@suzen.net>
- Loading branch information
1 parent
4bda883
commit 8705f64
Showing
7 changed files
with
236 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
...nsions.Microsoft.DependencyInjection/NATS.Extensions.Microsoft.DependencyInjection.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<IsTrimmable>true</IsTrimmable> | ||
|
||
<!-- NuGet Packaging --> | ||
<PackageTags>pubsub;messaging</PackageTags> | ||
<Description>ASP.NET Core and Generic Host support for NATS.Net.</Description> | ||
<IsPackable>true</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup Condition="'$(TargetFramework)' != 'net8.0'"> | ||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0"/> | ||
</ItemGroup> | ||
|
||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'"> | ||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0"/> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\NATS.Net\NATS.Net.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
135 changes: 135 additions & 0 deletions
135
src/NATS.Extensions.Microsoft.DependencyInjection/NatsBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
using System.Text.Json.Serialization; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.DependencyInjection.Extensions; | ||
using Microsoft.Extensions.Logging; | ||
using NATS.Client.Core; | ||
|
||
namespace NATS.Extensions.Microsoft.DependencyInjection; | ||
|
||
public class NatsBuilder | ||
{ | ||
private readonly IServiceCollection _services; | ||
private int _poolSize = 1; | ||
private Func<NatsOpts, NatsOpts>? _configureOpts; | ||
private Action<NatsConnection>? _configureConnection; | ||
private object? _diKey = null; | ||
|
||
public NatsBuilder(IServiceCollection services) | ||
=> _services = services; | ||
|
||
public NatsBuilder WithPoolSize(int size) | ||
{ | ||
_poolSize = Math.Max(size, 1); | ||
return this; | ||
} | ||
|
||
public NatsBuilder ConfigureOptions(Func<NatsOpts, NatsOpts> optsFactory) | ||
{ | ||
var previousFactory = _configureOpts; | ||
_configureOpts = opts => | ||
{ | ||
// Apply the previous configurator if it exists. | ||
if (previousFactory != null) | ||
{ | ||
opts = previousFactory(opts); | ||
} | ||
|
||
// Then apply the new configurator. | ||
return optsFactory(opts); | ||
}; | ||
return this; | ||
} | ||
|
||
public NatsBuilder ConfigureConnection(Action<NatsConnection> connectionOpts) | ||
{ | ||
_configureConnection = connectionOpts; | ||
return this; | ||
} | ||
|
||
public NatsBuilder AddJsonSerialization(JsonSerializerContext context) | ||
=> ConfigureOptions(opts => | ||
{ | ||
var jsonRegistry = new NatsJsonContextSerializerRegistry(context); | ||
return opts with { SerializerRegistry = jsonRegistry }; | ||
}); | ||
|
||
#if NET8_0_OR_GREATER | ||
public NatsBuilder WithKey(object key) | ||
{ | ||
_diKey = key; | ||
return this; | ||
} | ||
#endif | ||
|
||
public IServiceCollection Build() | ||
{ | ||
if (_poolSize != 1) | ||
{ | ||
if (_diKey == null) | ||
{ | ||
_services.TryAddSingleton<NatsConnectionPool>(provider => PoolFactory(provider)); | ||
_services.TryAddSingleton<INatsConnectionPool>(static provider => provider.GetRequiredService<NatsConnectionPool>()); | ||
_services.TryAddTransient<NatsConnection>(static provider => PooledConnectionFactory(provider, null)); | ||
_services.TryAddTransient<INatsConnection>(static provider => provider.GetRequiredService<NatsConnection>()); | ||
} | ||
else | ||
{ | ||
#if NET8_0_OR_GREATER | ||
_services.TryAddKeyedSingleton<NatsConnectionPool>(_diKey, PoolFactory); | ||
_services.TryAddKeyedSingleton<INatsConnectionPool>(_diKey, static (provider, key) => provider.GetRequiredKeyedService<NatsConnectionPool>(key)); | ||
_services.TryAddKeyedTransient(_diKey, PooledConnectionFactory); | ||
_services.TryAddKeyedTransient<INatsConnection>(_diKey, static (provider, key) => provider.GetRequiredKeyedService<NatsConnection>(key)); | ||
#endif | ||
} | ||
} | ||
else | ||
{ | ||
if (_diKey == null) | ||
{ | ||
_services.TryAddSingleton<NatsConnection>(provider => SingleConnectionFactory(provider)); | ||
_services.TryAddSingleton<INatsConnection>(static provider => provider.GetRequiredService<NatsConnection>()); | ||
} | ||
else | ||
{ | ||
#if NET8_0_OR_GREATER | ||
_services.TryAddKeyedSingleton(_diKey, SingleConnectionFactory); | ||
_services.TryAddKeyedSingleton<INatsConnection>(_diKey, static (provider, key) => provider.GetRequiredKeyedService<NatsConnection>(key)); | ||
#endif | ||
} | ||
} | ||
|
||
return _services; | ||
} | ||
|
||
private static NatsConnection PooledConnectionFactory(IServiceProvider provider, object? key) | ||
{ | ||
#if NET8_0_OR_GREATER | ||
if (key != null) | ||
{ | ||
var keyedConnection = provider.GetRequiredKeyedService<NatsConnectionPool>(key).GetConnection(); | ||
return keyedConnection as NatsConnection ?? throw new InvalidOperationException("Connection is not of type NatsConnection"); | ||
} | ||
#endif | ||
var connection = provider.GetRequiredService<NatsConnectionPool>().GetConnection(); | ||
return connection as NatsConnection ?? throw new InvalidOperationException("Connection is not of type NatsConnection"); | ||
} | ||
|
||
private NatsConnectionPool PoolFactory(IServiceProvider provider, object? diKey = null) | ||
{ | ||
var options = NatsOpts.Default with { LoggerFactory = provider.GetRequiredService<ILoggerFactory>() }; | ||
options = _configureOpts?.Invoke(options) ?? options; | ||
|
||
return new NatsConnectionPool(_poolSize, options, _configureConnection ?? (_ => { })); | ||
} | ||
|
||
private NatsConnection SingleConnectionFactory(IServiceProvider provider, object? diKey = null) | ||
{ | ||
var options = NatsOpts.Default with { LoggerFactory = provider.GetRequiredService<ILoggerFactory>() }; | ||
options = _configureOpts?.Invoke(options) ?? options; | ||
|
||
var conn = new NatsConnection(options); | ||
_configureConnection?.Invoke(conn); | ||
|
||
return conn; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/NATS.Extensions.Microsoft.DependencyInjection/NatsHostingExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace NATS.Extensions.Microsoft.DependencyInjection; | ||
|
||
public static class NatsHostingExtensions | ||
{ | ||
public static IServiceCollection AddNatsClient(this IServiceCollection services, Action<NatsBuilder>? buildAction = null) | ||
{ | ||
var builder = new NatsBuilder(services); | ||
buildAction?.Invoke(builder); | ||
|
||
builder.Build(); | ||
return services; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
tests/NATS.Extensions.Microsoft.DependencyInjection.Tests/MyJsonContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System.Text.Json.Serialization; | ||
|
||
namespace NATS.Extensions.Microsoft.DependencyInjection.Tests; | ||
|
||
[JsonSerializable(typeof(MyData))] | ||
internal partial class MyJsonContext : JsonSerializerContext; | ||
|
||
public record MyData | ||
{ | ||
public MyData(string name) => Name = name; | ||
|
||
public string Name { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters