首页 > 解决方案 > 如何从另一个 AppDomain 调用任意方法

问题描述

我正在制作一个插件管理器,它与第三方代码交互。我希望插件可以在运行时重新加载,并且还可以从插件访问第三方代码(在默认的 AppDomain 中)。

我尝试使用 AppDomains,但我还没有找到一种无需包装每个可用方法/对象即可调用任何方法的方法。

我查看了几个问题,例如,这个答案、其中的链接和这个答案提供了一些关于跨 AppDomain 通信如何工作的见解。

由于第二个答案,我已经成功地为在默认 AppDomain 中调用的单个方法创建了一个代理类,但这需要我为从插件调用的每个可能的方法调用添加一个。

我还尝试使用带有 Action 作为传递类型的代码,以允许插件传递一些要在默认 AppDomain 中执行的代码,但由于各种错误而失败。这是我的最后一次尝试。

主要应用:

[Serializable]
public sealed class DelegateWrapper<T1>
{
    private Action<T1> _someDelegate;

    public Action<T1> SomeDelegate
    {
        get
        {
            return _someDelegate;
        }
        set
        {
            if (value == null)
                _someDelegate = null;
            else
                _someDelegate = new myDelegateWrapper(value).Invoke;
        }
    }

    private sealed class myDelegateWrapper : MarshalByRefObject
    {
        public void Invoke(T1 input)
        {
            _delegate(input);
        }

        private Action<T1> _delegate;

        public myDelegateWrapper(Action<T1> dlgt)
        {
            _delegate = dlgt;
        }
    }
}


[Serializable]
public sealed class P
{
    public Action Action { get; }

    public P(Action action)
    {
        this.Action = action;
    }
}

private static readonly DelegateWrapper<P> PerformWrapper=new DelegateWrapper<P>();

public static void Init()
{
    PerformWrapper.SomeDelegate = p => p.Action();
}

在新的 AppDomain 中,Perform 方法正在调用 perform.SomeDelegate。

插件(也在新的 AppDomain 中执行):

Perform(new P(() =>
{
    //Third-party code
}));

这会导致一个异常,说它找不到我在插件 AppDomain 中手动加载的插件程序集。我假设它也在尝试将其加载到默认域中。有没有办法绕过它?

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Could not load file or assembly 'Plugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies

此处的完整堆栈跟踪:https ://pastebin.com/xZV7bXeV

标签: c#.netmonoappdomain

解决方案


推荐阅读