gpt4 book ai didi

xamarin - 如何在不编译 DLL 的情况下在 Android 中使用 MvvmCross 插件?

转载 作者:行者123 更新时间:2023-12-01 02:21:41 25 4
gpt4 key购买 nike

我在 Android 项目中使用自己的 MvvmCross 插件时遇到问题,因为 PluginLoader似乎期待 .Droid.dll它所在的确切 namespace 。

假设我有三个具有此文件夹和 namespace 结构的项目:

MyApp.Core:
Plugins/Settings/ISettings.cs
Plugins/Settings/PluginLoader.cs
MyApp.Droid:
Plugins/Settings/Settings.cs
Plugins/Settings/Plugin.cs
Bootstrap/SettingsPluginBootstrap.cs
MyApp.Touch:
Plugins/Settings/Settings.cs
Plugins/Settings/Plugin.cs
Bootstrap/SettingsPluginBootstrap.cs

iOS 项目按预期工作,并且没有问题地找到插件。

另一方面,Droid 项目失败并出现异常: Could not load file or assembly 'MyApp.Plugins.Settings.Droid.dll' or one of its dependencies.
如果我更改 PluginLoader 的命名空间来自 MyApp.Core.Plugins.Settings简单地说 MyApp ,插件有效;我猜它在寻找 MyApp.dll并找到它。但是,如果我的应用程序中有多个插件,它们应该都有自己的命名空间,它们不能都在 MyApp 中。命名空间。

目前我发现的唯一解决方法是为我创建的每个插件创建一个单独的项目,尽管这感觉有点不必要。

为什么 PluginLoader坚持寻找 <PluginLoader namespace>.Droid.dll Android 上的文件,当 PluginLoader在 iOS 上找到插件没有任何问题?

最佳答案

MvvmCross 插件旨在作为 IoC 之上的基于组件的层工作。

通过使用命名空间和程序集的共享模式以及几个帮助类(Plugin 和 PluginLoader),插件提供了一种共享和重用可移植 native 代码组件的方法。

iOS(和 Mac)使用稍微不同的插件加载方案的原因是 MonoTouch 的 AoT 编译器不允许动态 Assembly.Load 加载。

因此,iOS 必须使用与其他平台不同类型的 PluginManager 和不同类型的 Bootstrap 类。在 https://github.com/MvvmCross/MvvmCross/wiki/MvvmCross-plugins#how-plugins-are-loaded 的“如何加载插件”中有更多信息

如果您想将 Loader 类型的插件注册表添加到 Android 和 iOS,那么我认为您可以在自定义 PluginManager 类中执行此操作,然后可以在安装期间使用 protected override IMvxPluginManager CreatePluginManager() 的覆盖来创建它。

就像是:

public class MyPluginManager : MvxFilePluginManager, IMvxLoaderPluginManager
{
private readonly Dictionary<string, Func<IMvxPlugin>> _finders = new Dictionary<string, Func<IMvxPlugin>>();

public MyPluginManager(string platformDllPostfix, string assemblyExtension = "") : base(platformDllPostfix, assemblyExtension)
{
}

public IDictionary<string, Func<IMvxPlugin>> Finders
{
get { return _finders; }
}

protected override IMvxPlugin FindPlugin(Type toLoad)
{
var pluginName = toLoad.Namespace;
if (string.IsNullOrEmpty(pluginName))
{
throw new MvxException("Invalid plugin type {0}", toLoad);
}

Func<IMvxPlugin> finder;
if (_finders.TryGetValue(pluginName, out finder))
{
return finder();
}

return base.FindPlugin(toLoad);
}
}

在您的设置中使用以下方法初始化:
    protected override IMvxPluginManager CreatePluginManager()
{
return new MyPluginManager(".Droid", ".dll");
}

然后,您需要确保基于 loader 的插件使用基于 MvxLoaderPluginBootstrapAction 而不是 MvxPluginBootstrapAction 的引导类

作为另一种选择,如果您对单独重用插件不感兴趣-如果您不想发布大量单独的插件程序集-那么您可以将所有接口(interface)和实现放入一个程序集中-然后它们可以共享一个 BootstrapPluginPluginLoader 之间。

作为最后的替代方案,对于您的自定义需求,您始终可以考虑使用自己的自定义引导类 - 标准 Setup 将在您的 UI 程序集中创建和 Run 实现 IMvxBootstrapAction 的任何可构造类 - 因此您可以用一些自定义 SettingsPluginBootstrap 操作替换 Run适合您的应用程序需求。
public class SettingsBootstrapAction
: IMvxBootstrapAction
{
public void Run()
{
// my stuff here
}
}

关于xamarin - 如何在不编译 DLL 的情况下在 Android 中使用 MvvmCross 插件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20000008/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com