diff --git a/samples/MauiEmbedding/MauiEmbedding.MauiControls/AppBuildExtensions.cs b/samples/MauiEmbedding/MauiEmbedding.MauiControls/AppBuildExtensions.cs
index ee6bec10b7..078c5fc06e 100644
--- a/samples/MauiEmbedding/MauiEmbedding.MauiControls/AppBuildExtensions.cs
+++ b/samples/MauiEmbedding/MauiEmbedding.MauiControls/AppBuildExtensions.cs
@@ -7,6 +7,9 @@ public static class MauiAppBuilderExtensions
public static MauiAppBuilder UseCustomLibrary(this MauiAppBuilder builder)
{
CustomEntry.Init();
+ builder.ConfigureEssentials();
+ builder.Services.AddSingleton(ctx => Accelerometer.Default);
+ builder.Services.AddSingleton(ctx => Vibration.Default);
builder.ConfigureSyncfusionCore();
return builder;
}
diff --git a/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/AndroidManifest.xml b/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/AndroidManifest.xml
index 95ae07533a..addbe86965 100644
--- a/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/AndroidManifest.xml
+++ b/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/AndroidManifest.xml
@@ -1,4 +1,4 @@
-
+
-
+
diff --git a/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/Main.Android.cs b/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/Main.Android.cs
index 289716925c..bbbf0a5af5 100644
--- a/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/Main.Android.cs
+++ b/samples/MauiEmbedding/MauiEmbedding.Mobile/Android/Main.Android.cs
@@ -11,7 +11,7 @@
using Com.Nostra13.Universalimageloader.Core;
using Microsoft.UI.Xaml.Media;
-
+[assembly: UsesPermission(Android.Manifest.Permission.Vibrate)]
[assembly: Android.App.UsesPermission(Android.Manifest.Permission.BatteryStats)]
namespace MauiEmbedding.Droid;
diff --git a/samples/MauiEmbedding/MauiEmbedding.Mobile/MauiEmbedding.Mobile.csproj b/samples/MauiEmbedding/MauiEmbedding.Mobile/MauiEmbedding.Mobile.csproj
index 1ceb79e5a1..b57a973f37 100644
--- a/samples/MauiEmbedding/MauiEmbedding.Mobile/MauiEmbedding.Mobile.csproj
+++ b/samples/MauiEmbedding/MauiEmbedding.Mobile/MauiEmbedding.Mobile.csproj
@@ -39,7 +39,7 @@
-
+
diff --git a/samples/MauiEmbedding/MauiEmbedding/Presentation/MainViewModel.cs b/samples/MauiEmbedding/MauiEmbedding/Presentation/MainViewModel.cs
index 1e9a6b8e77..4fd66a5089 100644
--- a/samples/MauiEmbedding/MauiEmbedding/Presentation/MainViewModel.cs
+++ b/samples/MauiEmbedding/MauiEmbedding/Presentation/MainViewModel.cs
@@ -1,3 +1,6 @@
+using Microsoft.Maui.Devices;
+using Microsoft.Maui.Devices.Sensors;
+
namespace MauiEmbedding.Presentation;
public partial class MainViewModel : ObservableObject
@@ -10,12 +13,22 @@ public partial class MainViewModel : ObservableObject
public MainViewModel(
IStringLocalizer localizer,
IOptions appInfo,
- INavigator navigator)
+ INavigator navigator,
+ IAccelerometer accelerometer,
+ IVibration vibrate)
{
_navigator = navigator;
Title = "Main";
Title += $" - {localizer["ApplicationName"]}";
Title += $" - {appInfo?.Value?.Environment}";
+ accelerometer.ShakeDetected += Accelerometer_ShakeDetected;
+ accelerometer.Start(SensorSpeed.Default);
+ vibrate.Vibrate(3000);
+ }
+
+ private void Accelerometer_ShakeDetected(object? sender, EventArgs e)
+ {
+
}
public string? Title { get; }
diff --git a/src/Uno.Extensions.Maui.UI/MauiEmbedding.cs b/src/Uno.Extensions.Maui.UI/MauiEmbedding.cs
index c2fe4a62e8..d6a4652ecd 100644
--- a/src/Uno.Extensions.Maui.UI/MauiEmbedding.cs
+++ b/src/Uno.Extensions.Maui.UI/MauiEmbedding.cs
@@ -18,21 +18,7 @@ public static partial class MauiEmbedding
/// Optional lambda to configure the Maui app builder.
public static IApplicationBuilder UseMauiEmbedding(this IApplicationBuilder builder, Action? configure = null)
where TApp : MauiApplication
- {
- builder.App.UseMauiEmbedding(builder.Window, configure);
- return builder;
- }
-
- ///
- /// Registers Maui embedding in the Uno Platform app builder.
- ///
- /// The updated app builder.
- /// The IHost builder.
- /// The Uno app.
- /// The Main Application Window.
- /// Optional lambda to configure the Maui app builder.
- public static IHostBuilder UseMauiEmbedding(this IHostBuilder builder, Microsoft.UI.Xaml.Application app, Microsoft.UI.Xaml.Window window, Action? configure = null) =>
- builder.UseMauiEmbedding(app, window, configure);
+ => builder.Configure(hostBuilder => hostBuilder.UseMauiEmbedding(builder.App, builder.Window, configure));
///
/// Registers Maui embedding in the Uno Platform app builder.
@@ -44,13 +30,24 @@ public static IHostBuilder UseMauiEmbedding(this IHostBuilder builder, Microsoft
/// Optional lambda to configure the Maui app builder.
public static IHostBuilder UseMauiEmbedding(this IHostBuilder builder, Microsoft.UI.Xaml.Application app, Microsoft.UI.Xaml.Window window, Action? configure = null)
where TApp : MauiApplication
- => builder.ConfigureServices(services =>
+ {
+ MauiApp? mauiApp = default;
+ return builder
+ .UseServiceProviderFactory(ctx => new LinkedServiceProviderFactory(mauiApp!.Services))
+ //.UseServiceProviderFactory(ctx => new LinkedScopedServiceProviderFactory(mauiApp!.Services))
+ .ConfigureServices(services =>
{
// Expose the MauiApp to the Uno app via the IHost.Services
- var mauiApp = app.UseMauiEmbedding(window, configure);
+ mauiApp = app.UseMauiEmbedding(window, configure);
services.AddSingleton(mauiApp);
+ //services
+ // .AddSingleton(()=> app.UseMauiEmbedding(window, configure))
+ // .AddHostedService< MauiLoaderService>();
+
});
+ }
+
///
/// Registers Maui embedding with WinUI3 and WPF application builder.
///
@@ -83,10 +80,11 @@ public static MauiApp UseMauiEmbedding(this Microsoft.UI.Xaml.Application
{
WindowStateManager.Default.OnActivated(window, args);
};
-#endif
-
#endif
return mauiApp;
+#else
+ return default!;
+#endif
}
#if MAUI_EMBEDDING
@@ -168,3 +166,106 @@ public static MauiAppBuilder MapStyleHandler(this MauiAppBuilder build
}
*/
}
+
+internal record MauiLoaderService(MauiApp MauiApp) : IHostedService
+{
+ public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+ public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+}
+
+internal class LinkedServiceProviderFactory : IServiceProviderFactory
+{
+ private readonly IServiceProvider _childServiceProvider;
+
+ public LinkedServiceProviderFactory(IServiceProvider childServiceProvider)
+ {
+ _childServiceProvider = childServiceProvider;
+ }
+
+ public IServiceCollection CreateBuilder(IServiceCollection services)
+ {
+ return services
+ .AddSingleton< IServiceScopeFactory>(sp => new LinkedServiceScopeFactory(sp, _childServiceProvider));
+ }
+
+ public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder)
+ {
+ return new LinkedServiceProvider(containerBuilder.BuildServiceProvider(), _childServiceProvider);
+ }
+}
+internal class LinkedServiceScopeFactory : IServiceScopeFactory
+{
+ private readonly IServiceProvider _childServiceProvider;
+ private readonly IServiceProvider _serviceProvider;
+
+ public LinkedServiceScopeFactory(IServiceProvider serviceProvider, IServiceProvider childServiceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ _childServiceProvider = childServiceProvider;
+ }
+
+ public IServiceScope CreateScope()
+ {
+ var scope = _serviceProvider.CreateScope();
+ return new LinkedServiceScope(scope.ServiceProvider, _childServiceProvider);
+ }
+}
+
+public record LinkedServiceScope(IServiceProvider serviceProvider, IServiceProvider childServiceProvider) : IServiceScope
+{
+ public IServiceProvider ServiceProvider => new LinkedServiceProvider(serviceProvider, childServiceProvider);
+
+ public void Dispose() { }
+}
+
+//internal class LinkedScopedServiceProviderFactory : IServiceProviderFactory
+//{
+// private readonly IServiceProvider _childServiceProvider;
+
+// public LinkedScopedServiceProviderFactory(IServiceProvider childServiceProvider)
+// {
+// _childServiceProvider = childServiceProvider;
+// }
+// public IServiceScopeFactory CreateBuilder(IServiceCollection services)
+// {
+// return new DefaultServiceProviderFactory().CreateBuilder(services).BuildServiceProvider().GetRequiredService();
+// }
+
+// public IServiceProvider CreateServiceProvider(IServiceScopeFactory containerBuilder)
+// {
+// return new LinkedServiceProvider(containerBuilder.BuildServiceProvider(), _childServiceProvider);
+// //var scope = containerBuilder.CreateScope();
+// //var serviceProvider = scope.ServiceProvider;
+
+// //return new LinkedServiceProvider(serviceProvider, _childServiceProvider);
+// }
+//}
+
+internal class LinkedServiceProvider : IServiceProvider, IDisposable
+{
+ private readonly IServiceProvider _parent;
+ public readonly IServiceProvider _child;
+
+ public LinkedServiceProvider(IServiceProvider parent, IServiceProvider child)
+ {
+ _parent = parent;
+ _child = child;
+ }
+
+ public object? GetService(Type serviceType)
+ {
+ if(serviceType == typeof(IServiceScopeFactory))
+ {
+ return new LinkedServiceScopeFactory(_parent, _child);
+ }
+ return _parent.GetService(serviceType) ?? _child.GetService(serviceType);
+ }
+
+ public void Dispose()
+ {
+ if (_parent is IDisposable disposableChild)
+ {
+ disposableChild.Dispose();
+ }
+ }
+}
diff --git a/src/Uno.Extensions.Navigation.UI/FrameworkElementExtensions.cs b/src/Uno.Extensions.Navigation.UI/FrameworkElementExtensions.cs
index 6de5bf7bf0..1f2e01c958 100644
--- a/src/Uno.Extensions.Navigation.UI/FrameworkElementExtensions.cs
+++ b/src/Uno.Extensions.Navigation.UI/FrameworkElementExtensions.cs
@@ -14,6 +14,7 @@ public static class FrameworkElementExtensions
/// The attached IServiceProvider instance - scoped for use in this visual hierarchy
public static IServiceProvider AttachServiceProvider(this UIElement element, IServiceProvider services)
{
+ var factory = services.GetService();
var scopedServices = services.CreateScope().ServiceProvider;
element.SetServiceProvider(scopedServices);
return scopedServices;
diff --git a/src/Uno.Extensions.Navigation.UI/Navigators/ControlNavigator.cs b/src/Uno.Extensions.Navigation.UI/Navigators/ControlNavigator.cs
index 26f8e72a98..934e3a3904 100644
--- a/src/Uno.Extensions.Navigation.UI/Navigators/ControlNavigator.cs
+++ b/src/Uno.Extensions.Navigation.UI/Navigators/ControlNavigator.cs
@@ -227,7 +227,15 @@ protected virtual void UpdateRoute(Route? route)
services.AddScopedInstance(request);
- var created = services.GetService(mapping!.ViewModel);
+ object? created = default;
+ try
+ {
+ created = services.GetService(mapping!.ViewModel);
+ }
+ catch
+ {
+ if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug("Unable to create viewmodel directly via service provider, will fall back to trying the constructor");
+ }
if (created is not null)
{