I'm trying to merge plugins library projects into a single one (for example, Location + PhoneCallTask). It works perfectly with wp7, but I get an unhandled exception with monodroid:
Could not load file or assembly 'Cirrious.MvvmCross.Plugins.Location.Droid.dll'
Of course, the location plugin is referenced in 'Cirrious.MvvmCross.Plugins.Droid.dll', the merged library.
Is there a way to point to the merged library path?
Having considered your question more fully...
I'm still not entirely sure what a merge plugin is, but I think the problem you are seeing must be down to the way that MvvmCross-MonoDroid uses file conventions to load plugins while all the other platforms force the user to provide explicit factory methods for each plugin.
The reason for this difference is because the file conventions are (IMO) the nicest way of doing this... but all the other platforms put security and/or compilation issues in the way which meant that alternative mechanisms had to be used...
The easiest thing for you to do is probably to switch the setup of your MonoDroid app to use the loader conventions too.
To do this:
in Setup.cs override CreatePluginManager()
to:
protected override IMvxPluginManager CreatePluginManager() { var toReturn = new MvxLoaderBasedPluginManager(); var registry = new MvxLoaderPluginRegistry(".Droid", toReturn.Loaders); AddPluginsLoaders(registry); return toReturn; }
and then provide a AddPluginsLoaders()
implementation like:
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
}
Short answer:
I'm guessing you need to:
Longer answer (based on some notes I already had - will be published soon):
If you were to build an entirely new plugin, then you would:
This would be Portable Class library - say AlphaPage.MvvmCross.Plugins.Mega
Within that central shared PCL, you would put whatever portable code was available - often this might only be a few service Interface definitions - eg
public interface IAlphaService { ... }
and
public interface IPageService { ... }
You'd then add the PluginManager for that plugin which would just add the boiler-plate of:
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
}
For each platform, you would then implement the plugin - eg you might implement AlphaPage.MvvmCross.Plugins.Mega.WindowsPhone
and AlphaPage.MvvmCross.Plugins.Mega.Droid
Within each of these you will implement the native classes which provide the services:
public class MyAlphaService : IAlphaService { ... }
and
public class MyPageService : IPageService { ... }
Finally each plugin would then provide the boilerplate plugin implementation:
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
}
Each UI client will have to initialise the plugins.
This is done by the end UI client adding library references to:
Then, for WinRT, WindowsPhone and MonoTouch clients, you also need to provide a Loader accessor in setup.cs - like:
protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
{
loaders.AddConventionalPlugin<AlphaPage.MvvmCross.Plugins.Mega.WindowsPhone.Plugin>();
base.AddPluginsLoaders(loaders);
}
Note that Convention is used here - so it's important that AlphaPage.MvvmCross.Plugins.Mega.WindowsPhone.Plugin implements the WindowsPhone plugin for AlphaPage.MvvmCross.Plugins.Mega.PluginLoader
For MonoDroid clients, you don't need to add this setup step - because MonoDroid has less Assembly.Load restrictions than the other platforms - and ao can load the plugins from file. But for this to work, it's important that the assembly names match - if the PluginLoader is AlphaPage.MvvmCross.Plugins.Mega.PluginLoader
then the conventions will try to load the plugin from AlphaPage.MvvmCross.Plugins.Mega.Droid.dll
After this setup, then applications should finally be able to access the plugins by:
AlphaPage.MvvmCross.Plugins.Mega.PluginLoader.Instance.EnsureLoaded()
this.GetService<IAlphaService>()
or this.GetService<IPageService>()
Some plugins can be 'pure portable'
In this case they don't need any specialization for each platform, and no step 3 is required.
For an example of this, see the Json implementation - https://github.com/slodge/MvvmCross/tree/vnext/Cirrious/Plugins/Json
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.