Comment utiliser MvvmCross plugins dans Android sans compilation de la DLL?
Question
J'ai un problème à l'aide de mon propre MvvmCross plugins dans un projet Android, parce que le PluginLoader
semble attendre un .Droid.dll
exacte de l'espace de noms, il est en.
Dire que j'ai trois projets avec ce dossier et l'espace de la structure:
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
Le projet iOS fonctionne comme prévu, et trouve le plugin sans problème.
Le Droid projet sur l'autre main, échoue avec une exception: Could not load file or assembly 'MyApp.Plugins.Settings.Droid.dll' or one of its dependencies.
Si je change l'espace de noms de l' PluginLoader
à partir de MyApp.Core.Plugins.Settings
tout simplement MyApp
, le plugin fonctionne;Je suppose que cela ressemble pour l' MyApp.dll
et la trouve.Cependant, si j'ai plusieurs plugins dans mon application, ils doivent chacun avoir leur propre espace de noms, ils ne peuvent pas tous être dans le MyApp
espace de noms.
Actuellement, la seule solution que j'ai trouvé est de créer un projet distinct pour chaque plugin, j'ai créer, mais cela se sent un peu inutile.
Pourquoi ne l' PluginLoader
insister sur la recherche de la <PluginLoader namespace>.Droid.dll
de fichier sur Android, lorsque le PluginLoader
sur iOS trouve le plugin sans problème?
La solution
MvvmCross plugins sont conçus pour fonctionner comme un assemblage de couche sur le dessus de la Coi.
À l'aide d'un modèle partagé pour les espaces de noms et des assemblées, avec un couple de classes d'assistance (Plugin et PluginLoader), plug-ins fournissent un moyen de partager et de réutiliser portable les composants de code natif.
La raison pour laquelle iOS (Mac) un peu différent plugin le schéma de chargement est parce que le MonoTouch de AoT compilateur ne permettra pas dynamique Assembly.Load
le chargement.
En raison de cet iOS a utiliser un autre type de PluginManager
et d'un autre type de Bootstrap
classe pour les autres plates-formes.Il y a un peu plus d'infos à ce sujet dans "Comment les plugins sont chargés" dans https://github.com/MvvmCross/MvvmCross/wiki/MvvmCross-plugins#how-plugins-are-loaded
Si vous voulez ajouter l' Loader
type de plugin de registre pour Android ainsi que iOS, alors je pense que vous pourriez le faire dans un personnalisé PluginManager
classe et pourrait alors créer ce lors de l'Installation à l'aide d'une substitution de protected override IMvxPluginManager CreatePluginManager()
.
Quelque chose comme:
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);
}
}
initialisation de votre Installation à l'aide de:
protected override IMvxPluginManager CreatePluginManager()
{
return new MyPluginManager(".Droid", ".dll");
}
vous devez vous assurer que votre loader
en fonction des plugins utilise bootstrap classes à partir d' MvxLoaderPluginBootstrapAction
et pas MvxPluginBootstrapAction
Comme autre alternative, si vous n'êtes pas intéressé à réutiliser vos plugins individuellement - si vous préférez ne pas expédier beaucoup de personne plugin assemblées - ensuite, vous pouvez mettre toutes vos interfaces et implémentations dans une seule assemblée, et ils pourraient alors partager un seul Bootstrap
, Plugin
et PluginLoader
entre eux.
Comme une alternative finale, pour la réalisation de votre besoin, vous pouvez toujours envisager d'utiliser vos propres classes de bootstrap - la norme Setup
permettra de créer et de Run
tout constructable classe dans votre INTERFACE utilisateur de l'assemblée qui les met en œuvre IMvxBootstrapAction
- si vous pouviez remplacer SettingsPluginBootstrap
avec quelques personnalisé Run
l'action qui convient à vos applications besoins.
public class SettingsBootstrapAction
: IMvxBootstrapAction
{
public void Run()
{
// my stuff here
}
}