我正在尝试将来自不同程序集(在构建时未知)的类型加载为“动态”并在该类型上执行方法。我的目标是完全断开“插件”与父应用程序的连接,这样就不需要任何共享代码或通用接口类型。该接口通过加载类型上的预期方法签名来暗示。
这有效:
dynamic myObj = Assembly.Load("MyAssembly").CreateInstance("MyType");
myObj.Execute();
但是,这会将类型及其所有相关程序集加载到当前 AppDomain 中。我想修改它以允许我在单独的 AppDomain 中做同样的事情。
这有效,但不使用 dynamic 关键字,我需要知道我正在实例化的显式类型才能调用 Execute 方法:
var appDomain = AppDomain.CreateDomain(domainName, evidence, setup);
var myObj = appDomain.CreateInstanceAndUnwrap(assembly, type);
typeof(IMyInterface).InvokeMember("Execute", BindingFlags.InvokeMethod, null, myObj);
这基本上是我的目标案例,我一直试图让这样的事情起作用:
dynamic myObj = ad.CreateInstanceAndUnwrap(assembly, type);
myObj.Execute();
我一直以带有消息“'System.MarshalByRefObject'不包含'Execute'的定义”的RuntimeBinderException结束。这条消息是有道理的,确保它不包含“执行”的定义,但我知道我正在实例化的类型确实包含一个“执行”方法。我想透明代理在这里发生了一些事情,阻止了它的工作,但我不确定是什么。
我试图实例化的实际类如下所示:
[Serializable]
public class MyClass : MarshalByRefObject {
public void Execute() {
// do something
}
}
我也尝试过使用共享界面(不是我的主要目标,但我试图先解决这个问题),所以它看起来像:
[Serializable]
public class MyClass : MarshalByRefObject, IPlugin {
public void Execute() {
// do something
}
}
其中 IPlugin 是父应用程序中的已知类型,并且插件在构建时具有适当的引用,但这似乎也不起作用。
我猜在这一点上,不可能在 AppDomain 边界上将类型加载为动态。
有没有办法让它真正发挥作用?