diff --git a/src/Aspire.Hosting/ExecutableResourceBuilderExtensions.cs b/src/Aspire.Hosting/ExecutableResourceBuilderExtensions.cs
index b273a9b1b9..ac94b5da83 100644
--- a/src/Aspire.Hosting/ExecutableResourceBuilderExtensions.cs
+++ b/src/Aspire.Hosting/ExecutableResourceBuilderExtensions.cs
@@ -22,6 +22,20 @@ public static class ExecutableResourceBuilderExtensions
/// The arguments to the executable.
/// The .
public static IResourceBuilder AddExecutable(this IDistributedApplicationBuilder builder, string name, string command, string workingDirectory, params string[]? args)
+ {
+ return AddExecutable(builder, name, command, workingDirectory, (object[]?)args);
+ }
+
+ ///
+ /// Adds an executable resource to the application model.
+ ///
+ /// The .
+ /// The name of the resource.
+ /// The executable path. This can be a fully qualified path or a executable to run from the shell/command line.
+ /// The working directory of the executable.
+ /// The arguments to the executable.
+ /// The .
+ public static IResourceBuilder AddExecutable(this IDistributedApplicationBuilder builder, string name, string command, string workingDirectory, params object[]? args)
{
workingDirectory = PathNormalizer.NormalizePathForCurrentPlatform(Path.Combine(builder.AppHostDirectory, workingDirectory));
diff --git a/src/Aspire.Hosting/PublicAPI.Unshipped.txt b/src/Aspire.Hosting/PublicAPI.Unshipped.txt
index 17ce2b8d4a..5feb97f0f0 100644
--- a/src/Aspire.Hosting/PublicAPI.Unshipped.txt
+++ b/src/Aspire.Hosting/PublicAPI.Unshipped.txt
@@ -113,3 +113,5 @@ static Aspire.Hosting.ProjectResourceBuilderExtensions.AddProject(this Aspire.Ho
static Aspire.Hosting.ProjectResourceBuilderExtensions.AddProject(this Aspire.Hosting.IDistributedApplicationBuilder! builder, string! name, System.Action! configure) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
static readonly Aspire.Hosting.ApplicationModel.KnownResourceStates.TerminalStates -> System.Collections.Generic.IReadOnlyList!
static readonly Aspire.Hosting.ApplicationModel.KnownResourceStates.Waiting -> string!
+static Aspire.Hosting.ExecutableResourceBuilderExtensions.AddExecutable(this Aspire.Hosting.IDistributedApplicationBuilder! builder, string! name, string! command, string! workingDirectory, params object![]? args) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
+static Aspire.Hosting.ResourceBuilderExtensions.WithArgs(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, params object![]! args) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
diff --git a/src/Aspire.Hosting/ResourceBuilderExtensions.cs b/src/Aspire.Hosting/ResourceBuilderExtensions.cs
index 0e3dfa8b8d..40c16557ae 100644
--- a/src/Aspire.Hosting/ResourceBuilderExtensions.cs
+++ b/src/Aspire.Hosting/ResourceBuilderExtensions.cs
@@ -167,6 +167,18 @@ public static IResourceBuilder WithArgs(this IResourceBuilder builder,
return builder.WithArgs(context => context.Args.AddRange(args));
}
+ ///
+ /// Adds the arguments to be passed to a container resource when the container is started.
+ ///
+ /// The resource type.
+ /// The resource builder.
+ /// The arguments to be passed to the container when it is started.
+ /// The .
+ public static IResourceBuilder WithArgs(this IResourceBuilder builder, params object[] args) where T : IResourceWithArgs
+ {
+ return builder.WithArgs(context => context.Args.AddRange(args));
+ }
+
///
/// Adds a callback to be executed with a list of command-line arguments when a container resource is started.
///
diff --git a/tests/Aspire.Hosting.Tests/ExecutableResourceTests.cs b/tests/Aspire.Hosting.Tests/ExecutableResourceTests.cs
index 03ad72badc..794900eb99 100644
--- a/tests/Aspire.Hosting.Tests/ExecutableResourceTests.cs
+++ b/tests/Aspire.Hosting.Tests/ExecutableResourceTests.cs
@@ -15,6 +15,7 @@ public async Task AddExecutableWithArgs()
var appBuilder = DistributedApplication.CreateBuilder();
var testResource = new TestResource("test", "connectionString");
+ var testResource2 = new TestResource("test2", "anotherConnectionString");
var exe1 = appBuilder.AddExecutable("e1", "ruby", ".", "app.rb")
.WithEndpoint("ep", e =>
@@ -23,12 +24,13 @@ public async Task AddExecutableWithArgs()
e.AllocatedEndpoint = new(e, "localhost", 1234);
});
- var exe2 = appBuilder.AddExecutable("e2", "python", ".", "app.py")
+ var exe2 = appBuilder.AddExecutable("e2", "python", ".", "app.py", exe1.GetEndpoint("ep"))
+ .WithArgs("arg1", testResource)
.WithArgs(context =>
{
- context.Args.Add("arg1");
+ context.Args.Add("arg2");
context.Args.Add(exe1.GetEndpoint("ep"));
- context.Args.Add(testResource);
+ context.Args.Add(testResource2);
});
using var app = appBuilder.Build();
@@ -37,9 +39,13 @@ public async Task AddExecutableWithArgs()
Assert.Collection(args,
arg => Assert.Equal("app.py", arg),
+ arg => Assert.Equal("http://localhost:1234", arg),
arg => Assert.Equal("arg1", arg),
+ arg => Assert.Equal("connectionString", arg),
+ arg => Assert.Equal("arg2", arg),
arg => Assert.Equal("http://localhost:1234", arg),
- arg => Assert.Equal("connectionString", arg));
+ arg => Assert.Equal("anotherConnectionString", arg)
+ );
var manifest = await ManifestUtils.GetManifest(exe2.Resource);
@@ -51,9 +57,12 @@ public async Task AddExecutableWithArgs()
"command": "python",
"args": [
"app.py",
+ "{e1.bindings.ep.url}",
"arg1",
+ "{test.connectionString}",
+ "arg2",
"{e1.bindings.ep.url}",
- "{test.connectionString}"
+ "{test2.connectionString}"
]
}
""";