MvvmCross vnext:将插件与monodroid合并

时间:2012-10-17 09:52:26

标签: c# windows-phone-7 xamarin.ios xamarin.android mvvmcross

我正在尝试将插件库项目合并为一个(例如,Location + PhoneCallTask​​)。它与wp7完美配合,但我得到monodroid的未处理异常:

  

无法加载文件或程序集'Cirrious.MvvmCross.Plugins.Location.Droid.dll'

当然,位置插件在'Cirrious.MvvmCross.Plugins.Droid.dll'(合并库)中引用。

有没有办法指向合并的库路径?

2 个答案:

答案 0 :(得分:5)

更全面地考虑了你的问题......

我还不完全确定合并插件是什么,但我认为你看到的问题必须归结为MvvmCross-MonoDroid使用文件约定来加载插件的方式,而所有其他平台都迫使用户提供每个插件的显式工厂方法。

造成这种差异的原因是因为文件约定是(IMO)最好的方式...但是所有其他平台都将安全性和/或编译问题放在了必须使用替代机制的方式...

您最容易做的事情可能是切换MonoDroid应用程序的设置以使用加载程序约定。

要做到这一点:

    Setup.cs中的
  • 覆盖CreatePluginManager()

    protected override IMvxPluginManager CreatePluginManager()
    {
        var toReturn = new MvxLoaderBasedPluginManager();
        var registry = new MvxLoaderPluginRegistry(".Droid", toReturn.Loaders);
        AddPluginsLoaders(registry);
        return toReturn;
    }
    

然后提供AddPluginsLoaders()实现,如:

    protected virtual void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
    {
        loaders.AddConventionalPlugin<Cirrious.MvvmCross.Plugins.Visibility.Droid.Plugin>();
        loaders.AddConventionalPlugin<Cirrious.MvvmCross.Plugins.Location.Droid.Plugin>();
        loaders.AddConventionalPlugin<Cirrious.MvvmCross.Plugins.Phone.Droid.Plugin>();
        loaders.AddConventionalPlugin<AlphaPage.MvvmCross.Plugins.Mega.Droid.Plugin>();
        // etc
    }

答案 1 :(得分:2)

简短回答:

我猜你需要:

  • 检查您的命名空间和程序集名称是否都是相同的约定
  • 检查您是否在UI.Droid项目中引用了核心插件程序集和正确的插件实现

更长的答案(基于我已经拥有的一些笔记 - 将很快发布):

如果你要构建一个全新的插件,那么你会:

1。创建一个中央共享插件

这将是便携式类库 - 比如AlphaPage.MvvmCross.Plugins.Mega

在该中央共享PCL中,您可以放置​​任何可用的可移植代码 - 通常这可能只是一些服务接口定义 - 例如。

public interface IAlphaService { ... }

public interface IPageService { ... }

然后你会为这个插件添加PluginManager,它只会添加以下的样板:

public class PluginLoader
    : IMvxPluginLoader
    , IMvxServiceConsumer<IMvxPluginManager>
{
    public static readonly PluginLoader Instance = new PluginLoader();

    #region Implementation of IMvxPluginLoader

    public void EnsureLoaded()
    {
        var manager = this.GetService<IMvxPluginManager>();
        manager.EnsureLoaded<PluginLoader>();
    }

    #endregion
}

2。创建特定的插件实现

对于每个平台,您将实现插件 - 例如您可以实施AlphaPage.MvvmCross.Plugins.Mega.WindowsPhoneAlphaPage.MvvmCross.Plugins.Mega.Droid

在每个中,您将实现提供服务的本机类:

public class MyAlphaService : IAlphaService { ... } 

public class MyPageService : IPageService { ... }

最后,每个插件都会提供样板插件实现:

public class Plugin
    : IMvxPlugin
    , IMvxServiceProducer
{
    #region Implementation of IMvxPlugin

    public void Load()
    {
        // alpha registered as a singleton
        this.RegisterServiceInstance<IAlphaService>(new MyAlphaService());
        // page registered as a type
        this.RegisterServiceType<IPageService, MyPageService>();
    }

    #endregion
}

3。插件的实例化

每个UI客户端都必须初始化插件。

这是由最终UI客户端添加库引用来完成的:

  • 共享核心插件
  • 适当的插件实现

3.1 WinRT,WindowsPhone和MonoTouch

然后,对于 WinRT,WindowsPhone和MonoTouch 客户端,您还需要在setup.cs中提供一个Loader访问器 - 例如:

    protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
    {
        loaders.AddConventionalPlugin<AlphaPage.MvvmCross.Plugins.Mega.WindowsPhone.Plugin>();
        base.AddPluginsLoaders(loaders);
    }

请注意,此处使用了“约定” - 因此AlphaPage.MvvmCross.Plugins.Mega.WindowsPhone.Plugin为AlphaPage.MvvmCross.Plugins.Mega.PluginLoader实现WindowsPhone插件非常重要

3.2 MonoDroid

对于 MonoDroid 客户端,您无需添加此设置步骤 - 因为MonoDroid比其他平台具有更少的Assembly.Load限制 - 并且ao可以从文件加载插件。但为了实现这一点,重要的是程序集名称匹配 - 如果PluginLoader为AlphaPage.MvvmCross.Plugins.Mega.PluginLoader,则约定将尝试从AlphaPage.MvvmCross.Plugins.Mega.Droid.dll加载插件

4。使用插件服务

在此设置之后,应用程序最终应该能够通过以下方式访问插件:

  • 添加共享核心可移植库
  • 的引用
  • 在某个时候致电AlphaPage.MvvmCross.Plugins.Mega.PluginLoader.Instance.EnsureLoaded()
  • 然后使用this.GetService<IAlphaService>()this.GetService<IPageService>()
  • 访问各个服务

5。纯便携式插件

某些插件可以是“纯手提式”

在这种情况下,他们不需要为每个平台进行任何专业化,也不需要第3步。

有关此示例,请参阅Json实现 - https://github.com/slodge/MvvmCross/tree/vnext/Cirrious/Plugins/Json