我为现有项目创建了一个包装器,目前只正式支持Lua进行服务器端编码,服务器使用C#编码,因此使用反射来访问Lua中提供的方法并不是真正的问题。登记/>
我正在加载"脚本"到一个新的AppDomain,它工作正常,但是,一旦我传递一个委托(委托被服务器代码用作事件处理程序,通过其中一个方法),主机域尝试加载脚本的程序集,它违背了将脚本与主机域分离的最初目的,因此可以将它们卸载。
如果我确实为主机域提供了程序集,那么一切正常,直到我编辑代码并添加/删除/修改委托,然后断开对调用方法的每个引用,因为它依赖于程序集的旧副本,如我从字节数组加载它,以便可以在运行时修改程序集文件。
如何在不必加载程序集的情况下传递委托给主机AppDomain,这样脚本可以保持与托管AppDomain真正隔离并随意卸载/加载?
编辑:使用https://www.codeproject.com/Articles/831823/Plugin-framework上的插件框架项目中的SeparateAppDomain和MefLoader类我加载脚本如下:
托管域
上的Load()MefLoader mefLoader = SeparateAppDomain.CreateInstance<MefLoader>(path, path);
List<IServerScript> scripts = mefLoader.Load<IServerScript>();
foreach (IServerScript script in scripts)
{
ServerScript ss = ((ServerScript)script);
ss.CreateProxy(AppDomain.CurrentDomain);
}
在ServerScript类中(由MefLoader类加载到新的AppDomain上)
private Wrapper w = null;
internal void CreateProxy(AppDomain HostDomain)
{
Type wrappertype = typeof(Wrapper);
w = (Wrapper)HostDomain.CreateInstanceAndUnwrap(wrappertype.Assembly.FullName, wrappertype.FullName, false, BindingFlags.CreateInstance, null, new object[] { }, CultureInfo.InvariantCulture, null);
}
w
是回到托管域的方式,托管域处理有关服务器程序集反射的所有内容。
问题再现如下:
在ServerScript中
public void Test(Delegate d)
{
if (w != null) w.Test(d);
}
在继承将由MefLoader
加载的ServerScript的任何类中Test(new Action(() => { });
在Wrapper中
public void Test(Delegate d)
{
}
在ServerScript中调用w.Test(d)
之前,托管域不会尝试加载脚本程序集。
编辑2:进一步测试后,原因不是单独的appdomains,而是单独的程序集,除非我传递了在包装程序集中定义的委托,我最终遇到上述问题,这很可能是包装器尝试加载脚本程序集的原因,有什么方法可以从脚本程序集到代理程序(通常是一个Action&lt;&gt;具有不同数量的参数,具体取决于用例)包装器程序集而不将脚本程序集加载到包装器的域中?