- 
                Notifications
    You must be signed in to change notification settings 
- Fork 715
Add Aspire.Hosting.Maui (.NET MAUI) Android integration + OpenTelemetry connectivity through dev tunnels #12381
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
base: main
Are you sure you want to change the base?
Conversation
| 🚀 Dogfood this PR with: 
 curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12381Or 
 iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 12381" | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds comprehensive Android platform support to Aspire's MAUI hosting capabilities, enabling developers to run and debug MAUI applications on Android devices and emulators directly from Aspire. The implementation includes automatic environment variable forwarding via MSBuild targets files (required for Android) and introduces OpenTelemetry connectivity through dev tunnels to solve the localhost accessibility problem on mobile platforms.
Key Changes:
- Added Android device and emulator support with new resource types and extension methods
- Implemented environment variable forwarding for Android via MSBuild targets files
- Introduced WithOtlpDevTunnel()for automatic OpenTelemetry connectivity through dev tunnels
- Consolidated test files to reduce duplication using theory-based testing
Reviewed Changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description | 
|---|---|
| MauiAndroidExtensions.cs | New extension methods for adding Android devices and emulators to MAUI projects | 
| MauiAndroidDeviceResource.cs | Resource class representing physical Android device instances | 
| MauiAndroidEmulatorResource.cs | Resource class representing Android emulator instances | 
| MauiOtlpExtensions.cs | New WithOtlpDevTunnel()extension method for OpenTelemetry connectivity | 
| MauiAndroidEnvironmentAnnotation.cs | Event subscriber that generates MSBuild targets files for Android environment variables | 
| MauiEnvironmentHelper.cs | Helper utilities for creating Android environment targets files | 
| OtlpLoopbackResource.cs | Synthetic resource for service discovery of OTLP endpoints | 
| OtlpEndpointResolver.cs | Resolves OTLP endpoint configuration from standard environment variables | 
| OtlpDevTunnelConfigurationAnnotation.cs | Stores shared dev tunnel infrastructure across platforms | 
| IMauiPlatformResource.cs | Changed from internal to public and added IResourceWithParentinheritance | 
| MauiPlatformHelper.cs | Added ConfigureOtlpExporter()for DCP template placeholder replacement | 
| MauiPlatformExtensionsTests.cs | New consolidated test file using theory-based testing for all platforms | 
| MauiWindowsExtensionsTests.cs | Deleted - tests moved to consolidated file | 
| MauiMacCatalystExtensionsTests.cs | Deleted - tests moved to consolidated file | 
| MauiProjectResourceExtensions.cs | Added call to register MAUI-specific hosting services | 
| MauiHostingExtensions.cs | New internal extension for registering lifecycle hooks | 
| README.md | Added comprehensive documentation for Android support and dev tunnels | 
| Playground files | Updated example to demonstrate Android emulator with OTLP dev tunnel | 
        
          
                playground/AspireWithMaui/AspireWithMaui.MauiClient/EnvironmentPage.xaml.cs
          
            Show resolved
            Hide resolved
        
              
          
                src/Aspire.Hosting.Maui/Utilities/MauiAndroidEnvironmentAnnotation.cs
              
                Outdated
          
            Show resolved
            Hide resolved
        
      Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Simplifies MauiAndroidEnvironmentProcessedAnnotation by removing the unused TargetsFilePath property and constructor. Updates usage to reflect the new parameterless constructor and clarifies documentation to indicate the annotation is a marker for callback registration.
…r.cs" This reverts commit 8f17d90.
|  | ||
| // Add Android emulator with default emulator (uses running or default emulator) | ||
| mauiapp.AddAndroidEmulator() | ||
| .WithOtlpDevTunnel() // Needed to get the OpenTelemetry data to "localhost" | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not have this on by default? OTEL that just works by default is one of Aspire's most popular features.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I built it like this with the option in mind to provide a custom endpoint later or even use something entirely different like ngrok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Experimented with this a little but didn't get it quite right yet. My idea would then be: automatic dev tunnel when nothing is configured and when we detect a custom OTLP endpoint env var, then no dev tunnel and we just use that value.
People can then set it through SetEnvironment() or just as an env var on the host machine directly or if they choose to build some ngrok integration, they need to make sure to set it from there. Does that make sense?
If we want to explore down that path I think it might be good to do that in a follow-up PR.
| Can you show a screenshot of the dashboard resource pages when a MAUI project is used? I want to see how resources are displayed in the resource grid and graph. i.e. are parent/child resources nested correctly, do they have good icons, do relationships make sense, etc. | 
| @JamesNK I think that all looks good. Not thrilled about the otlp tunnel name, so any suggestions there are welcome, but then again maybe it also doesn't matter that much     | 
Replaces hardcoded default OTLP port and URL values with named constants and static readonly fields for improved maintainability and clarity.

Description
This PR adds Android platform support to Aspire's MAUI hosting capabilities, enabling developers to run and debug MAUI applications on Android devices and emulators directly from Aspire. The implementation follows the same architectural patterns as the existing Windows and Mac Catalyst implementations and includes OpenTelemetry connectivity through dev tunnels.
Follow up from #12284 and #11942 and #12342
Contributes to #4684
Features
AddAndroidDevice()orAddAndroidDevice(name, deviceId)for targeting specific devicesAddAndroidEmulator()orAddAndroidEmulator(name, emulatorId)for targeting specific emulatorsnet10.0-android) and fails fast with clear error messages if missingWithOtlpDevTunnel()extension method automatically creates dev tunnels for OpenTelemetry connectivity from mobile platforms that cannot reach localhostNew Files
MauiAndroidExtensions.cs- Extension methods for adding Android devices and emulators viaAddAndroidDevice()andAddAndroidEmulator()MauiAndroidDeviceResource.cs- Resource class representing a physical Android device instanceMauiAndroidEmulatorResource.cs- Resource class representing an Android emulator instanceMauiOtlpExtensions.cs- Extension methods for configuring OTLP connectivity viaWithOtlpDevTunnel()Otlp/OtlpLoopbackResource.cs- Synthetic resource for service discovery of OTLP endpointOtlp/OtlpEndpointResolver.cs- Resolves OTLP endpoint from configurationAnnotations/OtlpDevTunnelConfigurationAnnotation.cs- Stores shared dev tunnel infrastructureUtilities/MauiAndroidEnvironmentAnnotation.cs- Subscriber that generates MSBuild targets files for Android environment variablesUtilities/MauiEnvironmentHelper.cs- Helper for creating Android environment targets filesModified Files
IMauiPlatformResource.cs- Changed frominternaltopublic(required for generic constraint inWithOtlpDevTunnel<T>)MauiPlatformHelper.cs- AddedConfigureOtlpExporter()method that manually replaces DCP template placeholders for Android (follows Docker Compose/Azure App Service pattern)Aspire.Hosting.Maui.csproj- AddedAspire.Hosting.DevTunnelsproject referenceapi/Aspire.Hosting.Maui.cs- Updated API surface with new Android and OTLP extension methodsAspireWithMauito demonstrate Android device/emulator usage with OTLP dev tunnelPublic API
Usage Example
Architecture
Android Environment Variable Forwarding
Android applications launched via
dotnet runcannot receive environment variables through the standard process environment. This PR implements automatic environment variable forwarding through MSBuild:BeforeResourceStartedEventfor Android resources.targetsfile containing<AndroidEnvironmentVariables>items-p:CustomAfterMicrosoftCommonTargets={targetsPath}to pass the file to MSBuild%3BOTLP Dev Tunnel Implementation
Mobile platforms cannot reach
localhost, so this PR introducesWithOtlpDevTunnel()for automatic OpenTelemetry connectivity:OtlpLoopbackResourceimplementingIResourceWithEndpointsOtlpDevTunnelConfigurationAnnotationOtlpEndpointResolverreads configuration in priority order (unified endpoint → HTTP → gRPC → defaults)WithReference()for service discovery, reads tunnel URL, setsOTEL_EXPORTER_OTLP_ENDPOINT, cleans up temporary variablesChecklist
<remarks />and<code />elements on your triple slash comments?