Как использовать плагин mvvmcross, такой как плагин файла - PullRequest
1 голос
/ 11 октября 2019

Я использую mvvmcross версии 6.4.1 для разработки приложения для IOS, Android и WPF. Я искал во всем, чтобы использовать плагины. Кажется, нет примеров кода. В документации сказано установить Nuget как в мои основные, так и в пользовательские проекты приложений. Что я и сделал. Существуют ли какие-либо специальные регистрации / настройки / загрузки IOC, которые необходимо выполнить, прежде чем я смогу использовать плагин, и как мне использовать плагин? Внедряются ли они в конструктор или Нужно ли вручную извлекать их из контейнера IOC или new () их вверх.

Я установил nuget для плагина File в мой WPF UI и основной проект. Я добавил IMvxFileStore в один из конструкторов служб моего основного проекта, думая, что он автоматически добавляется в контейнер DI, но, похоже, он не вводится.

namespace My.Core.Project.Services
{
   public class SomeService : ISomeService
   {
      private IMvxFileStore mvxFileStore;
      public SomeService(IMvxFileStore mvxFileStore)
      {
         this.mvxFileStore = mvxFileStore;
      }

      public string SomeMethod(string somePath)
      {
          mvxFileStore.TryReadTextFile(somePath, out string content);

          return content;
      }
   }
}

App.xaml.cs

using MvvmCross.Core;
using MvvmCross.Platforms.Wpf.Views;
...

public partial class App : MvxApplicatin
{
   protected override void RegisterSetup()
   {
      this.RegisterSetupType<Setup<Core.App>>();
   }
}

App.cs

using MvvmCross;
using MvvmCross.ViewModels;
using My.Core.Project.Services;

public class App: MvxApplication
{
  public override void Initialize()
  {
    Mvx.IocProvider.RegisterType<ISomeService, SomeService>();
    RegisterCustomAppStart<AppStart>();
  }
}

AppStart.cs

using MvvmCross.Exceptions;
using MvvmCross.Navigation;
using MvvmCross.ViewModels;
using My.Core.Project.ViewModels;
using System;
using System.Threading.Tasks;

....

public class AppStart : MvxAppStart
{
  public AppStart(IMvxApplication application, IMvxNavigationService navigationService) : base(application, navigationService)
  {}

  public override Task NavigateToFirstViewModel(object hint = null)
  {
     try {
         return NavigationService.Navigate<FirstPageViewModel>();

     } catch {
         throw e.MvxWrap("Some error message {0}", typeof(FirstPageViewModel).Name);
     }
  }

}

Setup.cs в проекте WPF

using MvvmCross;
using MvvmCross.Base;
using MvvmCross.Platforms.Wpf.Core;
using MvvmCross.Plugin.File;
using MvvmCross.Plugin.Json;
using MvvmCross.ViewModels;
using My.Wpf.Project.Services;
...

public class Setup<T> : MvxWpfSetup
{
    public Setup() : base() {}

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

    protected override void InitializeFirstChange()
    {
        base.InitializeFirstChange();
        Mvx.IocProvider.RegisterType<ISomeWpfSpecificService>(() => new SomeWpfSpecificService());

    }

     protected override void InitializeLastChange()
     {
        base.InitializeLastChange();
     }
}

Я ожидаю, что мой сервисзагрузить, но вместо этого я получаю сообщение об ошибке MvxIoCResolveException: не удалось разрешить параметр для параметра mvxJsonConverter типа IMvxJsonConverter

ПРИМЕЧАНИЕ: я получаю одно и то же сообщение об ошибке как для плагина File, так и для Json. Плагин, который отображается первым вконструктор получает сообщение об ошибке, когда приложение пытается загрузить.

Правильно ли я использую или загружаю плагин?

ОБНОВЛЕНИЕ: Я вручную зарегистрировал плагины в пользовательском интерфейсеSetup.cs и он работает, но я не уверен, что это правильный способ сделать это.

Проект пользовательского интерфейса WPF Setup.cs

using MvvmCross;
using MvvmCross.Base;
using MvvmCross.Platforms.Wpf.Core;
using MvvmCross.Plugin.File;
using MvvmCross.Plugin.Json;
using MvvmCross.ViewModels;
using My.Wpf.Project.Services;
...

public class Setup<T> : MvxWpfSetup
{
    public Setup() : base() {}

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

    protected override void InitializeFirstChange()
    {
        base.InitializeFirstChange();
        Mvx.IocProvider.RegisterType<ISomeWpfSpecificService>(() => new SomeWpfSpecificService());
        Mvx.IoCProvider.RegisterType<IMvxFileStore, MvxFileStoreBase>();
        Mvx.IoCProvider.RegisterType<IMvxJsonConverter, MvxJsonConverter>();

    }

     protected override void InitializeLastChange()
     {
        base.InitializeLastChange();
     }
}


1 Ответ

0 голосов
/ 13 октября 2019

Да, вы используете плагин правильно, и я думаю, что на данный момент ваше решение вручную зарегистрировать плагин является жизнеспособным.

Корень проблемы находится в классе MvxSetup. Этот класс содержит метод LoadPlugins, который отвечает за загрузку плагинов MvvmCross, на которые ссылается ваш проект пользовательского интерфейса. Вот как LoadPlugins определяет, какие плагины загрузить:

  1. Получить все сборки, которые были загружены в контекст выполнения домена приложения.
  2. Найти типы в этих сборках, которые содержатMvxPluginAttribute.

Теперь проблема возникает на шаге 1. В проекте .NET Framework по умолчанию ваши ссылочные сборки не будут загружены в контекст выполнения, пока вы на самом деле не используете их вваш код. Поэтому, если вы не используете что-либо из вашей ссылки MvvmCross.Plugin.File в своем проекте пользовательского интерфейса, оно не будет загружено в ваш контекст выполнения и не будет найдено на шаге 1 и, следовательно, не будет зарегистрировано LoadPlugins. (хорошее чтение: когда загружается Зависимость сборки .NET )

Один из способов проверить это, выполнив следующее:

protected override void InitializeFirstChance()
{
    // Because a type of the MvvmCross.Plugin.File.Platforms.Wpf reference is
    // used here the assembly will now get loaded in the execution context
    var throwaway = typeof(Plugin);

    base.InitializeFirstChance();
}

С помощью приведенного выше кодавам не нужно вручную регистрировать Plugin.

Был запрос на получение , чтобы исправить это в среде MvvmCross, но это было отменено позжетак как это вызывало проблемы на других платформах.

На других платформах сборки плагинов будут загружаться в контекст выполнения без каких-либо хитростей, поэтому я бы сказал, что обновление документации MvvmCross о том, что вы должны зарегистрировать свой плагин вручную для WPF, будетполезно для других разработчиков в будущем.

...