From c6a74977a0f9d3b9d31cd6f40a6b98122adbd5d1 Mon Sep 17 00:00:00 2001 From: Oleksandr Liakhevych Date: Mon, 27 Mar 2023 02:09:47 +0300 Subject: [PATCH 1/2] Do not use Shell for URI navigation --- ...{Navigation.Shell.cs => Navigation.Uri.cs} | 29 +++-------- .../Navigation/Shell/MBBRouteFactory.cs | 49 ------------------- .../Components/SwitchablePages.razor | 8 +-- 3 files changed, 11 insertions(+), 75 deletions(-) rename src/BlazorBindings.Maui/Navigation/{Navigation.Shell.cs => Navigation.Uri.cs} (71%) delete mode 100644 src/BlazorBindings.Maui/Navigation/Shell/MBBRouteFactory.cs diff --git a/src/BlazorBindings.Maui/Navigation/Navigation.Shell.cs b/src/BlazorBindings.Maui/Navigation/Navigation.Uri.cs similarity index 71% rename from src/BlazorBindings.Maui/Navigation/Navigation.Shell.cs rename to src/BlazorBindings.Maui/Navigation/Navigation.Uri.cs index 4e70c613..9995f82b 100644 --- a/src/BlazorBindings.Maui/Navigation/Navigation.Shell.cs +++ b/src/BlazorBindings.Maui/Navigation/Navigation.Uri.cs @@ -7,12 +7,10 @@ namespace BlazorBindings.Maui; public partial class Navigation { - private readonly Dictionary RouteFactories = new(); - private readonly Dictionary NavigationParameters = new(); private List Routes; /// - /// Performs URI-based Shell navigation. This method is only available for Shell-based applications. + /// Performs URI-based navigation. /// /// URI to navigate to. /// Additional parameters to set for component. @@ -20,22 +18,14 @@ public async Task NavigateToAsync(string uri, Dictionary paramet { ArgumentNullException.ThrowIfNull(uri); - var shell = MC.Shell.Current - ?? throw new InvalidOperationException("URI-based navigation requires Shell-based application."); - Routes ??= FindRoutes(); var route = StructuredRoute.FindBestMatch(uri, Routes, parameters); if (route != null) { - NavigationParameters[route.Route.Type] = route; - if (!RouteFactories.TryGetValue(route.Route.BaseUri, out var routeFactory)) - { - throw new InvalidOperationException($"A route factory for URI '{uri}' could not be found."); - } - await routeFactory.CreateAsync(); - await shell.GoToAsync(route.Route.BaseUri); + var pars = GetParameters(route); + await Navigate(route.Route.Type, pars, NavigationTarget.Navigation, true); } else { @@ -67,13 +57,8 @@ private List FindRoutes() var structuredRoute = new StructuredRoute(route.Template, page); - //Register with XamarinForms so it can handle Navigation. - var routeFactory = new MBBRouteFactory(page, BuildPage); - MC.Routing.RegisterRoute(structuredRoute.BaseUri, routeFactory); - //Also register route in our own list for setting parameters and tracking if it is registered; result.Add(structuredRoute); - RouteFactories[structuredRoute.BaseUri] = routeFactory; } } @@ -103,11 +88,9 @@ private static Dictionary ConvertParameters(Type componentType, return convertedParameters; } - private Task BuildPage(Type componentType) + private Dictionary GetParameters(StructuredRouteResult route) { - var route = NavigationParameters[componentType]; - - var parameters = ConvertParameters(componentType, route.PathParameters); + var parameters = ConvertParameters(route.Route.Type, route.PathParameters); if (route.AdditionalParameters is not null) { @@ -124,6 +107,6 @@ private static Dictionary ConvertParameters(Type componentType, } } - return BuildElement(componentType, parameters); + return parameters; } } diff --git a/src/BlazorBindings.Maui/Navigation/Shell/MBBRouteFactory.cs b/src/BlazorBindings.Maui/Navigation/Shell/MBBRouteFactory.cs deleted file mode 100644 index cca45e60..00000000 --- a/src/BlazorBindings.Maui/Navigation/Shell/MBBRouteFactory.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -using Microsoft.Maui.Controls; -using MC = Microsoft.Maui.Controls; - -namespace BlazorBindings.Maui.ShellNavigation; - -//Based on the forms TypeRouteFactory https://github.com/xamarin/Xamarin.Forms/blob/9fd882e6c598a51bffbbb2f4de72c3bd9023ab41/Xamarin.Forms.Core/Routing.cs -internal class MBBRouteFactory : MC.RouteFactory -{ - private readonly Type _componentType; - private readonly Func> _pageFactory; - private MC.Page _element; - - public MBBRouteFactory(Type componentType, Func> pageFactory) - { - _componentType = componentType ?? throw new ArgumentNullException(nameof(componentType)); - _pageFactory = pageFactory ?? throw new ArgumentNullException(nameof(pageFactory)); - } - - public override MC.Element GetOrCreate() - { - return _element - ?? throw new InvalidOperationException("The target element of the Shell navigation is supposed to be created at this point."); - } - - public override MC.Element GetOrCreate(IServiceProvider services) => GetOrCreate(); - - public async Task CreateAsync() - { - _element = await _pageFactory(_componentType); - } - - public override bool Equals(object obj) - { - if ((obj is MBBRouteFactory otherRouteFactory)) - { - return otherRouteFactory._componentType == _componentType; - } - - return false; - } - - public override int GetHashCode() - { - return _componentType.GetHashCode(); - } -} diff --git a/src/BlazorBindings.UnitTests/Components/SwitchablePages.razor b/src/BlazorBindings.UnitTests/Components/SwitchablePages.razor index 4ce75608..1f5ee375 100644 --- a/src/BlazorBindings.UnitTests/Components/SwitchablePages.razor +++ b/src/BlazorBindings.UnitTests/Components/SwitchablePages.razor @@ -1,4 +1,6 @@ -@if (_switch) +@page "/switchable-pages" + +@if (_switch) {