Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for optionally generating a settings file #5015

Open
BretJohnson opened this issue Jul 22, 2024 · 6 comments
Open

Add support for optionally generating a settings file #5015

BretJohnson opened this issue Jul 22, 2024 · 6 comments
Labels
area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication untriaged New issue has not been triaged

Comments

@BretJohnson
Copy link
Member

BretJohnson commented Jul 22, 2024

Background and Motivation

There are various scenarios where it's useful to be able to launch a project in the "normal way", outside of Aspire launching it, but still have that project be configured with the right Aspire settings in order to connect to Aspire services and the Aspire OpenTelemetry dashboard.

Scenarios include:

  • MAUI and other .NET Mobile projects (e.g. Uno) where there may not be support initially for an integrated launch experience (Feature Request: .NET MAUI/mobile support 🌺 #4684)
  • MAUI and other .NET Mobile projects (e.g. Uno) when there is support for an integrated launch experience, but users still want the ability to launch outside of Aspire to support the typical inner loop scenario here https://twitter.com/GFlisch4u/status/1811635668327539021, just restarting MAUI app via Shift-F5 / F5 in VS
  • Test scenarios, where the .NET Android/iOS app is launched by Appium, xharness, or BrowserStack but still wants to talk the Aspire services for to run the UI tests - these technologies all expect to launch the app themselves, not have AppHost launch the app
  • Other client apps that are launched by some other program, a service, with custom CLI args from the command line, etc.
  • Web apps where the user wishes to set the web app as the startup project and still have that work

This API meets that need, by allowing the settings, normally passed via environment variables, to optionally be written to a settings file (e.g. a JSON file). Writing the settings file can happen in addition to building/launching the project normally, allowing both Aspire integrated and standalone startup to work, or it be the only option, with Aspire configured to not build/launch the project, just generate settings. The API here supports both use cases.

Proposed API

namespace Aspire.Hosting;

public static class ProjectResourceBuilderExtensions
{
+     /// <summary>
+    /// Adds a settings file to the project resource, to optionally persist settings that are normally set via environment variables.
+    /// The settings file can be generated with or without also launching the project.
+    /// </summary>
+    /// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param>
+    /// <param name="settingsFilePath">The path to settings file, absolute or relative to app host directory.</param>
+    /// <param name="settingsFileType">The settings file type, C# code (for use with IConfigurationBuilder.AddInMemoryCollection) or JSON (for use with IConfigurationBuilder.AddJsonFile).</param>
+    /// <param name="onlyGenerateSettings">Indicate whether to skip build/running this resource, only generating settings.</param>
+    public static IResourceBuilder<ProjectResource> WithSettingsFile(this IResourceBuilder<ProjectResource> builder, string settingsFilePath, SettingsFileType settingsFileType, bool onlyGenerateSettings)

+    /// <summary>
+    /// Adds a settings file to the project resource, to optionally persist settings that are normally set via environment variables.
+    /// The settings file can be generated with or without also launching the project.
+    /// </summary>
+    /// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param>
+    /// <param name="settingsFileOptions">The options to use for settings file generation.</param>
+    /// <returns></returns>
+    public static IResourceBuilder<ProjectResource> WithSettingsFile(this IResourceBuilder<ProjectResource> builder, SettingsFileOptions settingsFileOptions)

+    /// <summary>
+    /// Adds a .NET project to the application model, just generating a settings file for the project.
+    /// </summary>
+    /// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param>
+    /// <param name="name">The name of the resource. This name will be used for service discovery when referenced in a dependency.</param>
+    /// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
+    /// <remarks>
+    /// <para>
+    /// This overload of the <see cref="AddProject(IDistributedApplicationBuilder, string, string)"/> method adds a project to the application
+    /// model where Aspire only generates a settings file for the project, not otherwise trying to build or run it. This is useful for projects
+    /// that you wish to always launch manually, but have them connect to Aspire services and OTEL.
+    /// </para>
+    public static IResourceBuilder<ProjectResource> AddSettingsOnlyProject(this IDistributedApplicationBuilder builder, string name,
+        string settingsFilePath, SettingsFileType settingsFileType)
}

A draft PR implementing this API is here: #5016.

Usage Examples

builder.AddProject<Projects.MyFrontend>("mywebapp")
       .WithSettingsFile("..\\MyWebApp\\obj\\appsettingsAspire.g.json", SettingsFileType.Json, onlyGenerateSettings: false)
       .WithExternalHttpEndpoints()
       .WithReference(basketService)
       .WithReference(catalogService);

builder.AddSettingsOnlyProject("mymauiapp", "..\\MyMauiApp\\obj\\appsettingsAspire.g.cs", SettingsFileType.CSharp)
       .WithExternalHttpEndpoints()
       .WithReference(basketService)
       .WithReference(catalogService);

Alternative Designs

Initially, I considered having a separate project type for projects that generate settings. But allowing settings to optionally be generated for any .NET project, via a settings file IResourceAnnotation, allows more flexibility and emphasizes this is optional functionality in addition to integrated launch. Plus it required less changes to add. It seems like a nicer design all around.

Risks

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication label Jul 22, 2024
@BretJohnson BretJohnson changed the title Add optional support for generating a settings file Add support for optionally generating a settings file Jul 22, 2024
@maddymontaquila
Copy link
Member

I think this is unnecessary - Aspire can handle env variables, and this is just adding extra orchestration steps that arent necessary. A whole project for a settings file seems too much too.

@maddymontaquila
Copy link
Member

At no point does wiring things up from Aspire mean you cant switch to the individual startup project - so you can just always switch around. I have been running frontends separately to test them and it doesn't change anything.

@BretJohnson
Copy link
Member Author

I think this is unnecessary - Aspire can handle env variables, and this is just adding extra orchestration steps that arent necessary. A whole project for a settings file seems too much too.

Just to be clear, the proposal here doesn't (necessarily) add a whole project for the settings file. The settings file is an optional addition to an existing project (via WithSettingsFile).

@BretJohnson
Copy link
Member Author

At no point does wiring things up from Aspire mean you cant switch to the individual startup project - so you can just always switch around. I have been running frontends separately to test them and it doesn't change anything.

Yes, you can do this, but how do those projects get the right settings to use, to connect back to Aspire hosted services or the Aspire dashboard?

@mitchdenny
Copy link
Member

I'm not super enthused about this API myself. Seems to me the root of the issue is passing environment variables into mobile apps when you launch them. Android for example has the concept of a Wrap script:

https://developer.android.com/ndk/guides/wrap-script

Maybe there is some prior art here we can lean on which is idiomatic within each target ecosystem?

@BretJohnson
Copy link
Member Author

I'm not super enthused about this API myself. Seems to me the root of the issue is passing environment variables into mobile apps when you launch them. Android for example has the concept of a Wrap script:

https://developer.android.com/ndk/guides/wrap-script

Maybe there is some prior art here we can lean on which is idiomatic within each target ecosystem?

We can't use the Android wrap script because that's embedded into the app at build time. But we have another custom way to pass environment variables at launch time to Android apps, which looks like it should get into 17.12, so I think we'll have Aspire integrated launch support in VS 17.12 for MAUI. All that said, I still see value with this proposal. There are multiple scenarios, especially with mobile, where you want to be able to launch the app the traditional way (not thru AppHost in VS), but still use Aspire and dashboard. I added another one to the bulleted list above - device test tools like Appium, BrowserStack, xharness, etc. want to do the app deploy and launch - that's the way they are built. Tools like Appium will not just do the initial app launch but also relaunch the app for each test (optional) or on crash. All that tooling isn't built to launch through AppHost (especially not thru VS, as it's generally CLI based). But it's still useful to test with Aspire, running in CI or locally. And then there are the other scenarios I mentioned above, like especially faster inner dev loop, but also Rider, CLI, etc.

I just see this proposal as giving users more options & greater compatibility with existing workflows. Integrated launch is nice. But sometimes you want - or need - to launch the traditional way & still use Aspire services/dashboard. It's nice to support both.

@mitchdenny mitchdenny modified the milestone: Backlog Aug 12, 2024
@joperezr joperezr added the untriaged New issue has not been triaged label Oct 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication untriaged New issue has not been triaged
Projects
None yet
Development

No branches or pull requests

4 participants