Спецификация платформы c Служба вызывает исключение - MvvmCross, Xamarin. iOS - PullRequest
0 голосов
/ 06 мая 2020

Я разрабатываю приложение, в котором мне нужно использовать службы, специфичные для платформы c. Я сослался на так много всего в inte rnet и не мог найти способ заставить это работать. Думаю, даже документация MvvmCross не обновлялась.

В моей платформе c служба должна открывать диалоговые окна на каждой платформе в их собственном виде.

Так как я новичок в MvvmCross, я не мог придумать, как заставить эту работу . Любая помощь будет принята с благодарностью.

Примечание: Версия MvvmCross - 6.4.2

IPlatformSpecificDialogs.cs в Core / Common Project

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

IOSDialogs.cs в iOS Project

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

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

Setup.cs в iOS Project

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());
    }
}

MyView.cs в iOS Project

[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 в Core / Common Project

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

enter image description here

Это сообщение внутреннего исключения

Не удалось разрешить параметр для параметра platformSpecificDialogs типа IPlatformSpecificDialogs при создании MyProject.Core.ViewModels.MyViewModel. Вы можете передать его в качестве аргумента.

Это внутреннее исключение StackTrace

в MvvmCross.Io C .MvxIoCContainer.TryResolveParameter ( Тип System.Type, System.Reflection.ParameterInfo, параметрInfo, System.Object & parameterValue) [0x00020] в D: \ a \ 1 \ s \ MvvmCross \ IoC \ MvxIoCContainer.cs: 686 в MvvmCross.Io C .MvaraGetContainer. (Тип System.Type, System.Reflection.ConstructorInfo selectedConstructor, System.Collections.Generi c .IDictionary'2 [TKey, TValue] аргументы) [0x0003a] в D: \ a \ 1 \ s \ MvvmCross \ IoC \ MvxIoCContainer .cs: ​​646 в MvvmCross.Io C .MvxIoCContainer.IoCConstruct (тип System.Type, аргументы System.Collections.Generi c .IDictionary'2 [TKey, TValue]) [0x0002b] в D: \ a \ 1 \ s \ MvvmCross \ IoC \ MvxIoCContainer.cs: 416 в MvvmCross.Io C .MvxIoCContainer.IoCConstruct (тип System.Type) [0x00000] в D: \ a \ 1 \ s \ MvvmCross \ IoC: \ MvvmCross \ IoContainer 363 в MvvmCross.Io C .MvxIoCProvider.IoCConstruct (тип System.Type) [0x00 000] в D: \ a \ 1 \ s \ MvvmCross \ IoC \ MvxIoCProvider.cs: 149 в MvvmCross.ViewModels.MvxDefaultViewModelLocator.Load (System.Type viewModelType, MvvmCross.ViewModels.IMvalCross.ViewModels.IMVxundle .Navigation.EventArguments.IMvxNavigateEventArgs navigationArgs) [0x00000] в D: \ a \ 1 \ s \ MvvmCross \ ViewModels \ MvxDefaultViewModelLocator.cs: 56

1 Ответ

0 голосов
/ 09 мая 2020

Не удалось разрешить параметр для параметра platformSpecificDialogs типа IPlatformSpecificDialogs при создании MyProject.Core.ViewModels.MyViewModel. Вы можете передать его в качестве аргумента.

Исключение, с которым вы столкнулись, вызвано проблемой синхронизации. Чтобы решить эту проблему, вместо того, чтобы размещать регистрацию диалоговых окон c для платформы в InitializeLastChance(), поместите ее в InitializeFirstChance()

Поскольку я новичок в MVVMCross, я не мог придумать способ сделать эта работа. Любая помощь будет принята с благодарностью.

Что касается собственных диалогов, я бы посоветовал взглянуть на Пользовательские диалоги ACR , вы можете либо использовать кроссплатформенную библиотеку напрямую, либо использовать ее для вдохновения при создании вашей собственной реализации.


Пояснение

Жизненный цикл запуска MvvmCross состоит из двух этапов ( Ссылка на документацию ).

  1. InitializePrimary - запускается в основном контексте syn c (он же основной поток). Инициализирует Io C, механизм регистрации и другие компоненты ядра.
  2. InitializeSecondary - Работает в фоновом режиме (никогда в основном потоке). Создает некоторые другие службы платформы, такие как привязки, класс App и вызывает на нем 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) запускает последовательность запуска приложения. Это инициирует создание вашей первой модели представления, которая в вашем текущем случае зависит от службы, которая еще не была зарегистрирована у поставщика Io C. Это приводит к исключению, показывающему, что он не может разрешить параметр.

InitializeLastChance() использование будет нормально, если у вас нет немедленной потребности в службе. Обратите внимание на , что InitializePlatformServices() в настоящее время помечено как устаревшее и заменено InitializeFirstChance() ( Ссылка на документацию ).

...