繁体   English   中英

平台特定服务导致异常 - MvvmCross, Xamarin.iOS

[英]Platform Specific Service Causes an Exception - MvvmCross, Xamarin.iOS

我正在开发一个需要使用平台特定服务的应用程序。 我在互联网上引用了很多东西,但找不到一种方法来让它工作。 我猜即使是 MvvmCross 文档也没有更新。

我的平台特定服务是在每个平台中以它们的原生外观弹出对话框。

由于我是 MvvmCross 的新手,所以我想不出一种方法来完成这项工作。 任何帮助将不胜感激。

注: MvvmCross 版本为 6.4.2

核心/通用项目中的 IPlatformSpecificDialogs.cs

public interface IPlatformSpecificDialogs
{
    void Alert(string message, string title, string okButtonText);
}

iOS 项目中的 IOSDialogs.cs

public class IOSDialogs : IPlatformSpecificDialogs
{
    public IOSDialogs()
    {
    }

    public void Alert(string message, string title, string okButtonText)
    {
        Console.WriteLine("worked");
    }
}

iOS项目中的Setup.cs

public class Setup : MvxIosSetup<App>
{
    public Setup() : base()
    {
    }

    protected override IMvxApplication CreateApp()
    {
        return App.Instance;
    }

    protected override void InitializeLastChance()
    {
        base.InitializeLastChance();
        Mvx.IoCProvider.RegisterSingleton<IPlatformSpecificDialogs>(() => new IOSDialogs());
    }
}

iOS 项目中的 MyView.cs

[MvxFromStoryboard("Main")]
[MvxModalPresentation(WrapInNavigationController = false)]
public partial class MyView : BaseView<MyViewModel>
{
    public MyView(IntPtr handle) : base(handle)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
    }

    protected override void BindControllers()
    {
        var set = this.CreateBindingSet<MyView, MyViewModel>();
        set.Bind(AlertButton).To(vm => vm.AlertCommand);
        set.Apply();
    }
}

核心/通用项目中的 MyViewModel.cs

public class MyViewModel : BaseViewModel
{
    private readonly IPlatformSpecificDialogs _platformSpecificDialogs;

    public MyViewModel(IPlatformSpecificDialogs platformSpecificDialogs) : base()
    {
        _platformSpecificDialogs = platformSpecificDialogs;
    }

    public override Task Initialize()
    {
        return base.Initialize();
    }

    public IMvxCommand AlertCommand => new MvxCommand(PopupAlert);
    private void PopupAlert()
    {
        _platformSpecificDialogs.Alert("Title","Messege", "OK");
    }
}

导航到 MyView 时出现异常

在此处输入图像描述

这是内部异常消息

创建 MyProject.Core.ViewModels.MyViewModel 时,无法解析 IPlatformSpecificDialogs 类型的参数 platformSpecificDialogs 的参数。 您可以将其作为参数传递。

这是内部异常 StackTrace

在 MvvmCross.IoC.MvxIoCContainer.TryResolveParameter (System.Type type, System.Reflection.ParameterInfo parameterInfo, System.Object& parameterValue) [0x00020] 在 D:\a\1\s\MvvmCross\IoC\MvxIoCContainer.cs:686 在 MvvmCross .IoC.MvxIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo selectedConstructor, System.Collections.Generic.IDictionary'2[TKey,TValue] arguments) [0x0003a] in D:\a\1\s\MvvmCross\ IoC\MvxIoCContainer.cs:646 在 MvvmCross.IoC.MvxIoCContainer.IoCConstruct (System.Type 类型,System.Collections.Generic.IDictionary'2[TKey,TValue] 参数)[0x0002b] 在 D:\a\1\s\ MvvmCross\IoC\MvxIoCContainer.cs:416 在 MvvmCross.IoC.MvxIoCContainer.IoCConstruct (System.Type 类型) [0x00000] 在 D:\a\1\s\MvvmCross\IoC\MvxIoCContainer.cs:363 在 MvvmCross.IoC。 MvxIoCProvider.IoCConstruct (System.Type 类型) [0x00000] 在 D:\a\1\s\MvvmCross\IoC\MvxIoCProvider.cs:149 在 MvvmCross.ViewModels.MvxDefaultViewModelLocator.Load ( System.Type viewModelType, MvvmCross.ViewModels.IMvxBundle parameterValues, MvvmCross.ViewModels.IMvxBundle savedState, MvvmCross.Navigation.EventArguments.IMvxNavigateEventArgs navigationArgs) [0x00000] 在 D:\a\1\s\MvvmCross\ViewModels\MvxDefaultViewModelLocator.cs:56

创建 MyProject.Core.ViewModels.MyViewModel 时,无法解析 IPlatformSpecificDialogs 类型的参数 platformSpecificDialogs 的参数。 您可以将其作为参数传递。

您遇到的异常是由于时间问题。 要解决它而不是将特定于平台的对话框注册放在InitializeLastChance()中,请将其放在InitializeFirstChance()

由于我是 MVVMCross 的新手,所以我想不出一种方法来完成这项工作。 任何帮助将不胜感激。

在本机对话框方面,我建议查看ACR 用户对话框,您可以直接使用跨平台库,也可以在创建自己的自定义实现时使用它来获得灵感。


解释

MvvmCross 启动生命周期由两个阶段组成( 文档链接)。

  1. InitializePrimary - 在主同步上下文(又名主线程)上运行。 初始化 IoC、Logging 机制等核心部分。
  2. InitializeSecondary - 在后台运行(从不在主线程上)。 构造一些其他平台服务,如绑定、 App class 并对其调用Initialize 它最终注册 Views / ViewModels 查找。

初始化的方法调用如下( 文档链接

    // InitializePrimary 
    InitializeFirstChance();                // Earliest possible hook
    InitializeDebugServices();
    InitializePlatformServices();
    InitializeSettings();
    InitializeSingletonCache();

    // InitializeSecondary 
    PerformBootstrapActions();
    InitializeStringToTypeParser();
    InitializeViewModelFramework();
    var pluginManager = InitializePluginFramework();
    InitializeApp(pluginManager);           // App start up trigger here
    InitialiseViewModelTypeFinder();
    InitializeViewsContainer();
    InitiaiseViewDispatcher();
    InitializeViewLookup();
    InitialiseCommandCollectionBuilder();
    InitializeNavigationSerializer();
    InitializeInpcInterception();
    InitializeLastChance();                 // Last possible hook (async process)

您可以在这里看到InitializeFirstChance()作为InitializePrimary阶段中的第一个挂钩发生,而InitializeLastChance()作为InitializeSecondary阶段中的最后一个挂钩发生。 问题出现在InitializeSecondary方法InitializeApp(pluginManager)触发应用程序的启动序列的地方。 这会触发您的第一个视图 model 的创建,在您当前的情况下,该视图依赖于尚未向 IoC 提供程序注册的服务。 导致显示无法解析参数的异常。

如果您对服务没有即时需求, InitializeLastChance()的使用会很好。 请注意InitializePlatformServices()目前被标记为已弃用,取而代之的是InitializeFirstChance()文档链接)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM