Maui Prism .CreateWindow() 导航错误

问题描述 投票:0回答:1

我正在努力将 Xamarin.Forms 应用程序迁移到毛伊岛。在 MauiProgram 中,我们调用 MauiAppBuilder.UsePrism(),在 PrismAppBuilder 上调用 .RegisterTypes() 来注册服务和页面以进行导航。我们已确认服务正在初始化。最后,在 .OnAppStart 中,我们现在使用 .CreateWindow()。

.CreateWindow(async (container, navigation) =>
{
    AppCenter.Start("android=guid;ios=guid",
        typeof(Analytics), typeof(Crashes));

    var result = await navigation.NavigateAsync("/AppInitPage");
    if (!result.Success)
    {
        HandleNavigationError(result.Exception);
    }
})

这会导致导航不成功并导致以下异常: Microsoft.Maui.Controls.InvalidNavigationException:“预期导航失败。尚未创建根窗口。'

PrismAppBuilder:

            .UsePrism(prism =>
                prism
#if ANDROID
                    .RegisterTypes(Platforms.Android.PlatformRegistrations.RegisterPlatformTypes)
#endif
                    .RegisterTypes(containerRegistry =>
                    {
                        Barrel.ApplicationId = AppInfo.Current.PackageName;

                        //Register all of the services
                        containerRegistry.RegisterInstance<IPreferences>(Preferences.Default);
                        containerRegistry.RegisterInstance<IConnectivity>(Connectivity.Current);
                        containerRegistry.RegisterInstance<IAppInfo>(AppInfo.Current);
                        containerRegistry.RegisterInstance<IDeviceInfo>(DeviceInfo.Current);
                        containerRegistry.RegisterInstance<IVersionTracking>(VersionTracking.Default);
                        containerRegistry.RegisterSingleton<IAppSettings, AppSettings>();
                        containerRegistry.RegisterSingleton<IDb, Db>();
                        containerRegistry.RegisterSingleton<IAPI, API>();
                        containerRegistry.RegisterSingleton<ISyncManager, SyncManager>();
                        containerRegistry.RegisterSingleton<ISyncWorker, SyncWorker>();

                        containerRegistry.Register<IAuthentication, Authentication>();
                        containerRegistry.Register<IEncryptDecrypt, StringEncryptor>();
                        containerRegistry.Register<IHelpers, Helpers>();


                        //Register Pages
                        containerRegistry.RegisterForNavigation<ThemedNavigationPage>("NavigationPage");
                        containerRegistry.RegisterForNavigation<AboutPage>();
                        containerRegistry.RegisterForNavigation<AppInitPage>();
                        containerRegistry.RegisterForNavigation<TermsOfServicePage>();
                        containerRegistry.RegisterForNavigation<LoginPage>();
                        containerRegistry.RegisterForNavigation<CustomerSearchPage>();
                        containerRegistry.RegisterForNavigation<SettingsPage, SettingsPageViewModel>();
                        containerRegistry.RegisterForNavigation<CustomerPage>();
                        containerRegistry.RegisterForNavigation<FilesPage>();
                        containerRegistry.RegisterForNavigation<PhotoPage>();
                        containerRegistry.RegisterForNavigation<CustomerContactPage>();
                        containerRegistry.RegisterForNavigation<AssetPage>();
                        containerRegistry.RegisterForNavigation<ProductPage>();

                        //containerRegistry.RegisterGlobalNavigationObserver();

                        App.Container = containerRegistry.GetContainer();

                        App.Container.Resolve<IDb>().InitializeTables();
                    })
                    .AddGlobalNavigationObserver(context => context.Subscribe(x =>
                    {
                        if (x.Type == NavigationRequestType.Navigate)
                            Console.WriteLine($"Navigation: {x.Uri}");
                        else
                            Console.WriteLine($"Navigation: {x.Type}");

                        var status = x.Cancelled ? "Cancelled" : x.Result.Success ? "Success" : "Failed";
                        Console.WriteLine($"Result: {status}");

                        if (status == "Failed" && !string.IsNullOrEmpty(x.Result?.Exception?.Message))
                            Console.Error.WriteLine(x.Result.Exception.Message);
                    }))
                    .OnInitialized(_ =>
                    {
                        Microsoft.Maui.ApplicationModel.VersionTracking.Track();
                    })
                    .CreateWindow(async (container, navigation) =>
                    {
                        AppCenter.Start("android=guid;ios=guid",
                            typeof(Analytics), typeof(Crashes));

                        var result = await navigation.NavigateAsync("/AppInitPage");
                        if (!result.Success)
                        {
                            HandleNavigationError(result.Exception);
                        }
                    })
            );

异常堆栈:

[DOTNET] Navigation: http://localhost/AppInitPage
[DOTNET] Result: Failed
[DOTNET] A dependency issue occurred while resolving the ViewModel. Check the InnerException for the ContainerResolutionException
[DOTNET] Prism.Navigation.NavigationException: A dependency issue occurred while resolving the ViewModel. Check the InnerException for the ContainerResolutionException
[DOTNET]  ---> Prism.Mvvm.ViewModelCreationException: Unable to Create ViewModel for 'myApp.Views.AppInitPage'.
[DOTNET]  ---> Prism.Ioc.ContainerResolutionException: An unexpected error occurred while resolving 'myApp.ViewModels.AppInitPageViewModel'
[DOTNET]  ---> DryIoc.ContainerException: code: Error.UnableToResolveFromRegisteredServices;
[DOTNET] message: Unable to resolve resolution root myApp.ViewModels.AppInitPageViewModel with passed arguments [Constant(Microsoft.Maui.Dispatching.Dispatcher, typeof(Microsoft.Maui.Dispatching.Dispatcher))]
[DOTNET]   from container with scope {Name=null}
[DOTNET]  with Rules with {TrackingDisposableTransients, FuncAndLazyWithoutRegistration, SelectLastRegisteredFactory} and without {ThrowOnRegisteringDisposableTransient}
[DOTNET]  with FactorySelector=SelectLastRegisteredFactory
[DOTNET]  with Made={FactoryMethod=ConstructorWithResolvableArguments}
[DOTNET]   with normal and dynamic registrations:
[DOTNET]   (DefaultDynamicKey(0), {FactoryID=869, ImplType=myApp.ViewModels.AppInitPageViewModel, Reuse=TransientReuse, HasCondition})
[DOTNET]    at DryIoc.Throw.It(Int32 error, Object arg0, Object arg1, Object arg2, Object arg3) in /_/src/DryIoc/Container.cs:line 14774
[DOTNET]    at DryIoc.Container.TryThrowUnableToResolve(Request request) in /_/src/DryIoc/Container.cs:line 933
[DOTNET]    at DryIoc.Container.DryIoc.IContainer.ResolveFactory(Request request) in /_/src/DryIoc/Container.cs:line 915
[DOTNET]    at DryIoc.Container.ResolveAndCacheKeyed(Int32 serviceTypeHash, Type serviceType, Object serviceKey, IfUnresolved ifUnresolved, Object scopeName, Type requiredServiceType, Request preResolveParent, Object[] args) in /_/src/DryIoc/Container.cs:line 510
[DOTNET]    at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, Object serviceKey, IfUnresolved ifUnresolved, Type requiredServiceType, Request preResolveParent, Object[] args) in /_/src/DryIoc/Container.cs:line 469
[DOTNET]    at DryIoc.Resolver.Resolve(IResolver resolver, Type serviceType, Object[] args, IfUnresolved ifUnresolved, Type requiredServiceType, Object serviceKey) in /_/src/DryIoc/Container.cs:line 8673
[DOTNET]    at Prism.Container.DryIoc.DryIocScopedProvider.Resolve(Type type, ValueTuple`2[] parameters) in /_/src/Prism.Container.DryIoc/DryIocScopedProvider.cs:line 54
[DOTNET]    --- End of inner exception stack trace ---
[DOTNET]    at Prism.Container.DryIoc.DryIocScopedProvider.Resolve(Type type, ValueTuple`2[] parameters) in /_/src/Prism.Container.DryIoc/DryIocScopedProvider.cs:line 58
[DOTNET]    at Prism.PrismAppBuilder.DefaultViewModelLocator(Object view, Type viewModelType) in D:\a\Prism\Prism\src\Maui\Prism.Maui\PrismAppBuilder.cs:line 118
[DOTNET]    --- End of inner exception stack trace ---
[DOTNET]    at Prism.PrismAppBuilder.DefaultViewModelLocator(Object view, Type viewModelType) in D:\a\Prism\Prism\src\Maui\Prism.Maui\PrismAppBuilder.cs:line 126
[DOTNET]    at Prism.Mvvm.ViewModelLocationProvider.AutoWireViewModelChanged(Object view, Action`2 setDataContextCallback) in D:\a\Prism\Prism\src\Prism.Core\Mvvm\ViewModelLocationProvider.cs:line 136
[DOTNET]    at Prism.Mvvm.ViewModelLocator.Autowire(Object view) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Mvvm\ViewModelLocator.cs:line 85
[DOTNET]    at Prism.Mvvm.ViewRegistryBase.Autowire(BindableObject view) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Mvvm\ViewRegistryBase.cs:line 25
[DOTNET]    at Prism.Mvvm.ViewRegistryBase`1[[Microsoft.Maui.Controls.BindableObject, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].CreateView(IContainerProvider container, String name) in D:\a\Prism\Prism\src\Prism.Core\Mvvm\ViewRegistryBase{TBaseView}.cs:line 51
[DOTNET]    at Prism.Navigation.PageNavigationService.CreatePage(String segmentName) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Navigation\PageNavigationService.cs:line 903
[DOTNET]    --- End of inner exception stack trace ---
[DOTNET]    at Prism.Navigation.PageNavigationService.CreatePage(String segmentName) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Navigation\PageNavigationService.cs:line 920
[DOTNET]    at Prism.Navigation.PageNavigationService.CreatePageFromSegment(String segment) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Navigation\PageNavigationService.cs:line 943
[DOTNET]    at Prism.Navigation.PageNavigationService.ProcessNavigationForRootPage(String nextSegment, Queue`1 segments, INavigationParameters parameters, Nullable`1 useModalNavigation, Nullable`1 animated) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Navigation\PageNavigationService.cs:line 589
[DOTNET]    at Prism.Navigation.PageNavigationService.ProcessNavigation(Page currentPage, Queue`1 segments, INavigationParameters parameters, Nullable`1 useModalNavigation, Nullable`1 animated) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Navigation\PageNavigationService.cs:line 486
[DOTNET]    at Prism.Navigation.PageNavigationService.NavigateAsync(Uri uri, INavigationParameters parameters) in D:\a\Prism\Prism\src\Maui\Prism.Maui\Navigation\PageNavigationService.cs:line 378
**Microsoft.Maui.Controls.InvalidNavigationException:** 'Expected Navigation Failed. No Root Window has been created.'

我们已经检查了 AppInitPage 上的每个依赖项,以确保它尝试使用的依赖项和服务都已构建。然后我们应该期望调用 AppInitPage 的构造函数,但是这并没有发生,因此导航不断失败。相同的 MauiProgram(除了它使用 OnAppStart 而不是 CreateWindow)在另一个应用程序中使用并且工作没有问题。

maui prism .net-8.0
1个回答
0
投票

嗯,根据你的评论,作为维基答案:

这会导致导航不成功并导致 以下异常: Microsoft.Maui.Controls.InvalidNavigationException:'预期 导航失败。尚未创建根窗口。'

注册服务(monkeycache桶)可以避免这个错误。

© www.soinside.com 2019 - 2024. All rights reserved.