DLL을 컴파일하지 않고 Android에서 MvvmCross 플러그인을 사용하는 방법은 무엇입니까?

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

  •  20-12-2019
  •  | 
  •  

문제

Android 프로젝트에서 내 MvvmCross 플러그인을 사용하는 데 문제가 있습니다. PluginLoader 기대하는 것 같다 .Droid.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.

네임스페이스를 변경하면 PluginLoader ~에서 MyApp.Core.Plugins.Settings 단순히 MyApp, 플러그인이 작동합니다.찾는 것 같아요 MyApp.dll 그리고 그것을 발견합니다.그러나 내 앱에 여러 플러그인이 있는 경우 각각 고유한 네임스페이스를 가져야 하며 모두가 MyApp 네임스페이스.

현재 제가 찾은 유일한 해결 방법은 제가 만드는 각 플러그인에 대해 별도의 프로젝트를 만드는 것입니다. 하지만 이는 약간 불필요하다고 느껴집니다.

PluginLoader 꼭 찾아보라고 강요하다 <PluginLoader namespace>.Droid.dll Android에서 파일을 PluginLoader iOS에서는 문제 없이 플러그인을 찾을 수 있나요?

도움이 되었습니까?

해결책

MvvmCross 플러그인은 IoC 위에서 어셈블리 기반 레이어로 작동하도록 설계되었습니다.

플러그인은 몇 가지 도우미 클래스(Plugin 및 PluginLoader)와 함께 네임스페이스 및 어셈블리에 대한 공유 패턴을 사용하여 이식 가능한 네이티브 코드 구성 요소를 공유하고 재사용하는 방법을 제공합니다.

iOS(및 Mac)가 약간 다른 플러그인 로딩 방식을 사용하는 이유는 MonoTouch의 AoT 컴파일러가 동적 플러그인을 허용하지 않기 때문입니다. Assembly.Load 로딩.

이 때문에 iOS는 다른 유형의 PluginManager 그리고 다른 유형의 Bootstrap 다른 플랫폼에 대한 클래스입니다.이에 대한 자세한 정보는 "플러그인 로드 방법"에 있습니다. https://github.com/MvvmCross/MvvmCross/wiki/MvvmCross-plugins#how-plugins-are-loaded


추가하고 싶으시다면 Loader iOS뿐만 아니라 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 그리고는 아니다 MvxPluginBootstrapAction


또 다른 대안으로, 플러그인을 개별적으로 재사용하는 데 관심이 없다면(많은 개별 플러그인 어셈블리를 제공하지 않으려는 경우) 모든 인터페이스와 구현을 하나의 단일 어셈블리에 넣을 수 있습니다. Bootstrap, Plugin 그리고 PluginLoader 그들 사이에.


최종 대안으로, 사용자 정의 요구 사항에 따라 언제든지 사용자 정의 부트스트랩 클래스 사용을 고려할 수 있습니다. Setup 생성하고 Run 구현하는 UI 어셈블리의 생성 가능한 클래스 IMvxBootstrapAction - 그래서 당신은 교체 할 수 있습니다 SettingsPluginBootstrap 어떤 관습으로 Run 앱 요구 사항에 맞는 작업을 수행합니다.

public class SettingsBootstrapAction
    : IMvxBootstrapAction
{
    public void Run()
    {
        // my stuff here
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top