File: Embedding\EmbeddingExtensions.cs
Web Access
Project: src\src\Core\src\Core.csproj (Microsoft.Maui)
#if ANDROID || IOS || MACCATALYST || WINDOWS
using System;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.Hosting;
 
#if ANDROID
using PlatformWindow = Android.App.Activity;
using PlatformApplication = Android.App.Application;
#elif IOS || MACCATALYST
using PlatformWindow = UIKit.UIWindow;
using PlatformApplication = UIKit.IUIApplicationDelegate;
#elif WINDOWS
using PlatformWindow = Microsoft.UI.Xaml.Window;
using PlatformApplication = Microsoft.UI.Xaml.Application;
#endif
 
namespace Microsoft.Maui.Embedding;
 
/// <summary>
/// A set of extension methods that allow for embedding a MAUI view within a native application.
/// </summary>
internal static class EmbeddingExtensions
{
	/// <summary>
	/// Enables MAUI to be embedded in native application by injecting embedded handlers into the service collection.
	/// </summary>
	/// <param name="builder">The <see cref="MauiAppBuilder"/> instance.</param>
	/// <param name="platformApplication">The native application instance.</param>
	/// <returns>The <see cref="MauiAppBuilder"/> instance.</returns>
	internal static MauiAppBuilder UseMauiEmbedding(this MauiAppBuilder builder, PlatformApplication? platformApplication = null)
	{
#if ANDROID
		platformApplication ??= (Android.App.Application)Android.App.Application.Context;
#elif IOS || MACCATALYST
		platformApplication ??= UIKit.UIApplication.SharedApplication.Delegate;
#elif WINDOWS
		platformApplication ??= Microsoft.UI.Xaml.Application.Current;
#endif
 
		if (platformApplication is null)
		{
			throw new InvalidOperationException("Platform application instance is required and was not able to be detected.");
		}
 
		// Register the current native application that is currently running.
		builder.Services.AddSingleton(platformApplication);
 
		// Register the IPlatformApplication for the embedded application.
		builder.Services.AddSingleton<EmbeddedPlatformApplication>(svc => new EmbeddedPlatformApplication(svc));
 
		builder.Services.AddScoped<EmbeddedWindowProvider>(svc => new EmbeddedWindowProvider());
 
		// Returning null is acceptable here as the platform window is optional.
		// However, we do not know for sure until we resolve it.
		builder.Services.AddScoped<PlatformWindow>(svc => svc.GetRequiredService<EmbeddedWindowProvider>().PlatformWindow!);
 
		// Register an initializer as we need a platform application to be
		// instantiated as soon as possible. In a typical app, this would be
		// done by the platform-specific bootstrapper.
		builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IMauiInitializeService, EmbeddedInitializeService>(svc => new EmbeddedInitializeService()));
 
		return builder;
	}
 
	/// <summary>
	/// Creates a window-scoped <see cref="IMauiContext"/> for the provided platform window.
	/// </summary>
	/// <param name="mauiApp">The <see cref="MauiApp"/> instance.</param>
	/// <param name="platformWindow">The native window instance to create the context for.</param>
	/// <param name="window">The MAUI window instance to connect to the platform window.</param>
	/// <returns>The window-scoped <see cref="IMauiContext"/> instance.</returns>
	internal static IMauiContext CreateEmbeddedWindowContext(this MauiApp mauiApp, PlatformWindow platformWindow, IWindow window)
	{
		// Get the embedded application instance.
		var embeddedApp = mauiApp.Services.GetRequiredService<EmbeddedPlatformApplication>();
 
		// Create a window context for the platform window that was provided.
		var windowContext = embeddedApp.Context.MakeWindowScope(platformWindow, out var windowScope);
 
		// Add the platform window to the service provider.
		var wndProvider = windowContext.Services.GetRequiredService<EmbeddedWindowProvider>();
		wndProvider.SetWindow(platformWindow, window);
 
		// Connect the platform window to the MAUI window in order for lifecycle events to work.
		window.ToHandler(windowContext);
 
		return windowContext;
	}
 
	/// <summary>
	/// An initializer to make sure the <see cref="IPlatformApplication.Current"/> is populated.
	/// </summary>
	private class EmbeddedInitializeService : IMauiInitializeService
	{
		public void Initialize(IServiceProvider services) =>
			services.GetRequiredService<EmbeddedPlatformApplication>();
	}
}
#endif