c# - 如何从另一个 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
解决方案
推荐阅读
- node.js - 我可以让我的 cdn 使用令牌直接联系 firebase 存储,然后只返回文件而不返回令牌吗?
- karate - Karate - get a value that starts with a char and appears from last from json response
- php - Laravel 6存储数据问题即使没有错误
- join - 求和每个客户的销售额计算不加起来
- git - Pycharm合并不显示所有分支
- c++ - C++11 STL 在编译时从子树中生成树的方法?
- c# - 如果 c# 中的整数值为 0,则忽略对象的属性
- hybris - 如何在 hybris 中更改同步工作人员数量
- chart.js - 如何在一个标题内的 Charts.js 中插入多个值?
- powershell - AD 不复制新组,因此我可以授予它访问文件夹的权限