DLLをコンパイルせずにAndroidのMVVMcrossプラグインの使用方法は?

StackOverflow https://stackoverflow.com//questions/20000008

  •  20-12-2019
  •  | 
  •  

質問

Androidプロジェクトでは、Androidプロジェクト内の私自身のMVVMCrossプラグインを使用している問題があります。

このフォルダとネームスペース構造を持つ3つのプロジェクトがあるとします。

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プロジェクトは予想どおりに機能し、問題なくプラグインを見つけます。

一方、ドロイドプロジェクトは例外で失敗します.PluginLoader

.Droid.dllからCould not load file or assembly 'MyApp.Plugins.Settings.Droid.dll' or one of its dependencies.の名前空間を単にPluginLoaderに変更すると、プラグインが機能します。 MyApp.Core.Plugins.Settingsを探すと思い、それを見つけます。ただし、アプリに複数のプラグインがある場合は、それぞれが独自のネームスペースを持つ必要があります。これはすべてMyAppネームスペースに入ることはできません。

現在見つかった唯一の回避策は、私が作成したプラグインごとに別のプロジェクトを作成することですが、これは少し不要です。

MyApp.dllがAndroid上のMyAppファイルを探しているのは、問題なくプラグインを見つけたときに、Android上のPluginLoaderファイルを探しているのですか?

役に立ちましたか?

解決

MVVMCROSSプラグインは、IOCの上にアセンブリベースのレイヤーとして機能するように設計されています。

ネームスペースやアセンブリの共有パターンを使用することで、ヘルパークラス(Plugin and PluginLoader)とともに、プラグインはポータブルのネイティブコードコンポーネントを共有して再利用する方法を提供します。

iOS(およびMAC)がわずかに異なるプラグインローディング方式を使用する理由は、MonotouchのAOTコンパイラが動的Assembly.Loadロードを許可しないためです。

このiOSのために、他のプラットフォームに異なるタイプのPluginManagerとさまざまな種類のBootstrapクラスを使用する必要があります。 https://github.com/mvvmcross/mvvmcross/wiki/mvvmcross-plugins#####-ルーダード


iOSだけでなく、LoaderタイプのプラグインレジストリをAndroidに追加したい場合は、カスタム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からBootstrapクラスを使用して、MvxPluginBootstrapAction

ではないことを確認する必要があります。


別の代替案として、あなたが個別にあなたのプラグインを再利用することに興味がないならば - あなたがたくさんの個々のプラグインアセンブリを出荷しないであれば、あなたはすべてのあなたのインターフェースと実装を1つの一つのアセンブリに置くことができます - そして彼らはそれを共有することができます単一のBootstrapPluginおよびそれらの間のPluginLoader


カスタムのニーズに応じて、あなたのカスタムのニーズに応じてあなた自身のカスタムブートストラップクラスを使用することを常に考えることができます - 標準のSetupは、Runを実装するUIアセンブリ内の構築可能クラスを作成し、IMvxBootstrapActionを実装することができます。あなたのアプリのニーズに合ったSettingsPluginBootstrapアクション。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top