如何使用 mvvmcross 插件,例如文件插件
How to use an mvvmcross plugin such as the file plugin
我正在使用 mvvmcross 版本 6.4.1 为 IOS、Android 和 WPF 开发应用程序。
我到处搜索我要使用的插件。似乎没有代码示例。文档说要在我的核心和 ui 应用程序项目中安装 nuget。我做到了。在我可以使用该插件之前是否需要完成任何特殊的 IOC registration/setup/or 加载,我该如何使用该插件?它们是被注入到构造函数中还是我必须手动将它们从 IOC 容器中拉出或 new () 它们。
我已经为文件插件安装了 nuget 到我的 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 of imvxJsonConverter
解析参数
注意:对于文件和 Json 插件,我收到相同的错误消息,在构造函数中首先列出的插件在应用程序尝试加载时收到错误消息。
我是否正确使用或加载了插件?
更新: 我在 UI Setup.cs 中手动注册了插件,它正在工作,但我不确定这是否是正确的方法做吧。
WPFUI 项目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();
}
}
是的,您正在正确使用插件,我认为目前您手动注册插件的解决方案是可行的。
问题的根源位于MvxSetup
class。这个 class 包含方法 LoadPlugins
负责加载你的 UI 项目引用的 MvvmCross 插件。这就是 LoadPlugins
确定要加载的插件的方式:
- 获取所有已加载到应用程序域的执行上下文中的程序集。
- 在这些程序集中查找包含
MvxPluginAttribute
. 的类型
现在问题出现在步骤 1 中。在 .NET Framework 项目中,默认情况下,您引用的程序集不会加载到执行上下文中,直到您在代码中实际使用它们。因此,如果您不在 UI 项目中使用 MvvmCross.Plugin.File 引用中的某些内容,它将不会加载到您的执行上下文中,也不会在第 1 步中找到,因此它不会由 LoadPlugins
注册。 (好读:when does a .NET assembly Dependency get loaded)
我测试过的一种方法是这样做:
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
。
后来出现了pull request to fix this in the MvvmCross framework but this has been reverted,因为它在其他平台上引起了问题。
在其他平台上,插件程序集将在没有任何技巧的情况下加载到执行上下文中,所以我想说更新 MvvmCross 文档,说明您必须为 WPF 手动注册插件,这对将来的其他开发人员很有用。
我正在使用 mvvmcross 版本 6.4.1 为 IOS、Android 和 WPF 开发应用程序。 我到处搜索我要使用的插件。似乎没有代码示例。文档说要在我的核心和 ui 应用程序项目中安装 nuget。我做到了。在我可以使用该插件之前是否需要完成任何特殊的 IOC registration/setup/or 加载,我该如何使用该插件?它们是被注入到构造函数中还是我必须手动将它们从 IOC 容器中拉出或 new () 它们。
我已经为文件插件安装了 nuget 到我的 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 of imvxJsonConverter
解析参数注意:对于文件和 Json 插件,我收到相同的错误消息,在构造函数中首先列出的插件在应用程序尝试加载时收到错误消息。
我是否正确使用或加载了插件?
更新: 我在 UI Setup.cs 中手动注册了插件,它正在工作,但我不确定这是否是正确的方法做吧。
WPFUI 项目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();
}
}
是的,您正在正确使用插件,我认为目前您手动注册插件的解决方案是可行的。
问题的根源位于MvxSetup
class。这个 class 包含方法 LoadPlugins
负责加载你的 UI 项目引用的 MvvmCross 插件。这就是 LoadPlugins
确定要加载的插件的方式:
- 获取所有已加载到应用程序域的执行上下文中的程序集。
- 在这些程序集中查找包含
MvxPluginAttribute
. 的类型
现在问题出现在步骤 1 中。在 .NET Framework 项目中,默认情况下,您引用的程序集不会加载到执行上下文中,直到您在代码中实际使用它们。因此,如果您不在 UI 项目中使用 MvvmCross.Plugin.File 引用中的某些内容,它将不会加载到您的执行上下文中,也不会在第 1 步中找到,因此它不会由 LoadPlugins
注册。 (好读:when does a .NET assembly Dependency get loaded)
我测试过的一种方法是这样做:
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
。
后来出现了pull request to fix this in the MvvmCross framework but this has been reverted,因为它在其他平台上引起了问题。
在其他平台上,插件程序集将在没有任何技巧的情况下加载到执行上下文中,所以我想说更新 MvvmCross 文档,说明您必须为 WPF 手动注册插件,这对将来的其他开发人员很有用。