diff --git a/src/Aspire.Hosting.Nats/NatsBuilderExtensions.cs b/src/Aspire.Hosting.Nats/NatsBuilderExtensions.cs
index 470d03f261b..1929ef06ddd 100644
--- a/src/Aspire.Hosting.Nats/NatsBuilderExtensions.cs
+++ b/src/Aspire.Hosting.Nats/NatsBuilderExtensions.cs
@@ -21,6 +21,9 @@ public static class NatsBuilderExtensions
/// The .
public static IResourceBuilder AddNats(this IDistributedApplicationBuilder builder, string name, int? port = null)
{
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentNullException.ThrowIfNull(name);
+
var nats = new NatsServerResource(name);
return builder.AddResource(nats)
.WithEndpoint(targetPort: 4222, port: port, name: NatsServerResource.PrimaryEndpointName)
@@ -54,7 +57,11 @@ public static IResourceBuilder WithJetStream(this IResourceB
/// The resource builder.
/// The .
public static IResourceBuilder WithJetStream(this IResourceBuilder builder)
- => builder.WithArgs("-js");
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+
+ return builder.WithArgs("-js");
+ }
///
/// Adds a named volume for the data folder to a NATS container resource.
@@ -64,8 +71,13 @@ public static IResourceBuilder WithJetStream(this IResourceB
/// A flag that indicates if this is a read-only volume.
/// The .
public static IResourceBuilder WithDataVolume(this IResourceBuilder builder, string? name = null, bool isReadOnly = false)
- => builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/var/lib/nats", isReadOnly)
- .WithArgs("-sd", "/var/lib/nats");
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+
+ return builder.WithVolume(name ?? VolumeNameGenerator.CreateVolumeName(builder, "data"), "/var/lib/nats",
+ isReadOnly)
+ .WithArgs("-sd", "/var/lib/nats");
+ }
///
/// Adds a bind mount for the data folder to a NATS container resource.
@@ -75,7 +87,11 @@ public static IResourceBuilder WithDataVolume(this IResource
/// A flag that indicates if this is a read-only mount.
/// The .
public static IResourceBuilder WithDataBindMount(this IResourceBuilder builder, string source, bool isReadOnly = false)
- => builder.WithBindMount(source, "/var/lib/nats", isReadOnly)
- .WithArgs("-sd", "/var/lib/nats");
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentNullException.ThrowIfNull(source);
+ return builder.WithBindMount(source, "/var/lib/nats", isReadOnly)
+ .WithArgs("-sd", "/var/lib/nats");
+ }
}
diff --git a/src/Aspire.Hosting.Nats/NatsServerResource.cs b/src/Aspire.Hosting.Nats/NatsServerResource.cs
index de5937c1587..a4d60962e6a 100644
--- a/src/Aspire.Hosting.Nats/NatsServerResource.cs
+++ b/src/Aspire.Hosting.Nats/NatsServerResource.cs
@@ -1,6 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
namespace Aspire.Hosting.ApplicationModel;
///
@@ -8,7 +11,7 @@ namespace Aspire.Hosting.ApplicationModel;
///
/// The name of the resource.
-public class NatsServerResource(string name) : ContainerResource(name), IResourceWithConnectionString
+public class NatsServerResource(string name) : ContainerResource(ThrowIfNull(name)), IResourceWithConnectionString
{
internal const string PrimaryEndpointName = "tcp";
internal const string PrimaryNatsSchemeName = "nats";
@@ -26,4 +29,7 @@ public class NatsServerResource(string name) : ContainerResource(name), IResourc
public ReferenceExpression ConnectionStringExpression =>
ReferenceExpression.Create(
$"{PrimaryNatsSchemeName}://{PrimaryEndpoint.Property(EndpointProperty.Host)}:{PrimaryEndpoint.Property(EndpointProperty.Port)}");
+
+ private static string ThrowIfNull([NotNull] string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
+ => argument ?? throw new ArgumentNullException(paramName);
}
diff --git a/tests/Aspire.Hosting.Nats.Tests/NatsPublicApiTests.cs b/tests/Aspire.Hosting.Nats.Tests/NatsPublicApiTests.cs
new file mode 100644
index 00000000000..e26f63b27cf
--- /dev/null
+++ b/tests/Aspire.Hosting.Nats.Tests/NatsPublicApiTests.cs
@@ -0,0 +1,93 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Aspire.Hosting.ApplicationModel;
+using Aspire.Hosting.Utils;
+using Xunit;
+
+namespace Aspire.Hosting.Nats.Tests;
+
+public class NatsPublicApiTests
+{
+ [Fact]
+ public void AddNatsContainerShouldThrowWhenBuilderIsNull()
+ {
+ IDistributedApplicationBuilder builder = null!;
+ const string name = "Nats";
+
+ var action = () => builder.AddNats(name);
+
+ var exception = Assert.Throws(action);
+ Assert.Equal(nameof(builder), exception.ParamName);
+ }
+
+ [Fact]
+ public void AddNatsContainerShouldThrowWhenNameIsNull()
+ {
+ var builder = TestDistributedApplicationBuilder.Create();
+ string name = null!;
+
+ var action = () => builder.AddNats(name);
+
+ var exception = Assert.Throws(action);
+ Assert.Equal(nameof(name), exception.ParamName);
+ }
+
+ [Fact]
+ public void WithJetStreamShouldThrowWhenBuilderIsNull()
+ {
+ IResourceBuilder builder = null!;
+
+ var action = () => builder.WithJetStream();
+
+ var exception = Assert.Throws(action);
+ Assert.Equal(nameof(builder), exception.ParamName);
+ }
+
+ [Fact]
+ public void WithDataVolumeShouldThrowWhenBuilderIsNull()
+ {
+ IResourceBuilder builder = null!;
+
+ var action = () => builder.WithDataVolume();
+
+ var exception = Assert.Throws(action);
+ Assert.Equal(nameof(builder), exception.ParamName);
+ }
+
+ [Fact]
+ public void WithDataBindMountShouldThrowWhenBuilderIsNull()
+ {
+ IResourceBuilder builder = null!;
+ const string source = "/data";
+
+ var action = () => builder.WithDataBindMount(source);
+
+ var exception = Assert.Throws(action);
+ Assert.Equal(nameof(builder), exception.ParamName);
+ }
+
+ [Fact]
+ public void WithDataBindMountShouldThrowWhenSourceIsNull()
+ {
+ var builder = TestDistributedApplicationBuilder.Create();
+ var nats = builder.AddNats("Nats");
+ string source = null!;
+
+ var action = () => nats.WithDataBindMount(source);
+
+ var exception = Assert.Throws(action);
+ Assert.Equal(nameof(source), exception.ParamName);
+ }
+
+ [Fact]
+ public void CtorNatsServerResourceShouldThrowWhenNameIsNull()
+ {
+ string name = null!;
+
+ var action = () => new NatsServerResource(name);
+
+ var exception = Assert.Throws(action);
+ Assert.Equal(nameof(name), exception.ParamName);
+ }
+}