Wednesday, October 17, 2012

Build a new plugin for mvvmcrosss

Update: This advice below is for vNext. For more up to date advice, see: http://stackoverflow.com/questions/16788164/custom-plugin-in-mvvmcross

-----

 1. Create a central shared plugin

This would be Portable Class library - say MyCompany.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 - e.g.

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
}

2. Create the specific plugin implementations

For each platform, you would then implement the plugin - e.g. you might implement MyCompany.MvvmCross.Plugins.Mega.WindowsPhone and MyCompany .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
}

3. Instantiation of plugins

Each UI client will have to initialise the plugins.
This is done by the end UI client adding library references to:
  • the shared core plugin
  • the appropriate plugin implementation

3.1 WinRT, WindowsPhone and MonoTouch

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<MyCompany.MvvmCross.Plugins.Mega.WindowsPhone.Plugin>();

        base.AddPluginsLoaders(loaders);
    }

Note that Convention is used here - so it's important that MyCompany.MvvmCross.Plugins.Mega.WindowsPhone.Plugin implements the WindowsPhone plugin for MyCompany.MvvmCross.Plugins.Mega.PluginLoader

3.2 MonoDroid

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 MyCompany.MvvmCross.Plugins.Mega.Droid.dll

4. Use of plugin services

After this setup, then applications should finally be able to access the plugins by:
  • adding a reference the Shared core portable library
  • at some time calling MyCompany.MvvmCross.Plugins.Mega.PluginLoader.Instance.EnsureLoaded()
  • then accessing the individual services using this.GetService() or this.GetService()

5. Pure portable plugins

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

No comments:

Post a Comment