2013-11-15 75 views
3

我用我自己的MvvmCross插件,Android項目中的一個問題,因爲PluginLoader似乎期待確切的命名空間中的一個.Droid.dll如何在Android中使用MvvmCross插件而無需編譯DLL?

說我有這個文件夾,命名空間結構三個項目:

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.

如果我從MyApp.Core.Plugins.Settings改變PluginLoader的命名空間來簡單地MyApp,該插件;我想它會查找MyApp.dll並找到它。但是,如果我的應用程序中有多個插件,則它們應該都有自己的名稱空間,它們不能全部位於MyApp名稱空間中。

目前我發現的唯一解決方法是爲我創建的每個插件創建一個單獨的項目,雖然這感覺有點不必要。

爲什麼PluginLoader堅持在Android上尋找<PluginLoader namespace>.Droid.dll文件,當iOS上的PluginLoader發現插件沒有任何問題?

+1

感謝您提出一個有趣的問題 - 我認爲您正在探索的空間與當前使用插件的區域略有不同(但帶有共享區域)。我非常喜歡這個核心項目的想法,它能夠爲ui項目定義「契約」 - 所以已經記錄下這個想法 - https://github.com/MvvmCross/MvvmCross/issues/496 – Stuart

回答

3

MvvmCross插件被設計爲在IoC之上作爲基於裝配的層工作。

通過使用名稱空間和程序集的共享模式以及一些輔助類(Plugin和PluginLoader),插件提供了一種共享和重用可移植本地代碼組件的方法。

iOS(和Mac)使用稍微不同的插件加載方案的原因是因爲MonoTouch的AoT編譯器不允許動態加載Assembly.Load

因爲這個iOS必須使用不同類型的PluginManager和不同類型的Bootstrap類到其他平臺。有一個關於這個更多的信息中如果你想添加的Loader型插件註冊表到Android以及iOS的,那麼我想你可以在自定義做到這一點「如何插件加載」在https://github.com/MvvmCross/MvvmCross/wiki/MvvmCross-plugins#how-plugins-are-loaded


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


As另一種選擇是,如果你不想單獨重用你的插件 - 如果你不想單獨運送大量單獨的插件程序集 - 那麼你可以將所有的接口和實現集成到一個單獨的程序集中 - 然後他們可以共享一個Bootstrap,PluginPluginLoader之間。


作爲最後的選擇,爲您定製的需求,你總是可以考慮使用自己的自定義自舉類 - 標準Setup將創建並Run在UI組件中的任何施工的類,它實現IMvxBootstrapAction - 這樣你就可以取代SettingsPluginBootstrap,其中一些自定義Run操作適合您的應用需求。

public class SettingsBootstrapAction 
    : IMvxBootstrapAction 
{ 
    public void Run() 
    { 
     // my stuff here 
    } 
} 
+0

感謝很多可行的替代品,我想現在我更瞭解插件。目前,我正在'Setup.cs'中重寫'InitializePlatformServices',並用例如'Mvx.ConstructAndRegisterSingleton ()',同時保持iOS的默認插件行爲,但感覺有點混亂;混合插件模式和IoC容器。 –

相關問題