我正在尝试将来自不同程序集(在构建时不知道)的类型加载为"动态"并在该类型上执行方法.我的目标是完全断开'插件'与父应用程序的连接,这样就不需要任何共享代码或通用接口类型.通过加载类型上的预期方法签名来暗示接口.
这有效:
dynamic myObj = Assembly.Load("MyAssembly").CreateInstance("MyType");
myObj.Execute();
Run Code Online (Sandbox Code Playgroud)
但是,这会将类型加载到当前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);
Run Code Online (Sandbox Code Playgroud)
这基本上是我的目标案例,我一直试图让这样的工作:
dynamic myObj = ad.CreateInstanceAndUnwrap(assembly, type);
myObj.Execute();
Run Code Online (Sandbox Code Playgroud)
我一直以RuntimeBinderException结束,消息"'System.MarshalByRefObject'不包含'Execute'的定义".这条消息有意义,确定它不包含'Execute'的定义,但我知道我实例化的类型确实包含'Execute'方法.我想这里有一些透明代理正在阻止它工作,但我不确定是什么.
我试图实例化的实际类看起来像这样:
[Serializable]
public class MyClass : MarshalByRefObject {
public void Execute() {
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
我也尝试过这个共享接口(不是我的主要目标,但我想先把它弄清楚)所以它看起来像:
[Serializable]
public class MyClass : MarshalByRefObject, IPlugin {
public void Execute() {
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
其中IPlugin是父应用程序中的已知类型,并且插件在构建时具有适当的引用,但这似乎也不起作用.
我猜这一点是不可能在AppDomain边界上加载一个动态类型.
有没有办法让它真正起作用?
我正在尝试构建一个看起来像这样的对象:
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items
{
return items.AsEnumerable().ToList<AnotherObject>();
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用NHibernate作为我的DAL并将其直接映射到items字段,所有这些都可以正常工作.
我也使用Windows Workflow,复制器活动不适用于通用IList.(http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63)这基本上迫使我使用List <>包装而不是IList < >.这当然打破了直接的NHibernate映射,因为NHibernate的IList实现不能直接转换为List.
**编辑:Windows Workflow要求实际上意味着我将失去对列表的类型安全访问,无论它需要IList.
现在的目标是序列化/反序列化此对象.这适用于二进制序列化,但当我尝试反序列化时,底层的NHibernate代理对象会出现nhibernate错误.
所以我尝试了xml序列化.序列化工作正常,并在序列化的xml文件中给出了我很好的具体类定义,它完全剥离了nhibernate代理.但是,当尝试反序列化时,我无法将项目添加到列表中作为items.AsEnumerable.ToList调用将不允许项目通过.Add方法添加到基础列表.
有没有人对此有任何想法?我是以错误的方式来做这件事的吗?
**编辑:NHibernate具体类是NHibernate.Collection.Generic.PersistentGenericBag确实直接实现IList.但是,我失去了通用列表的所有类型安全的好处.这让我回到必须为每个子对象编写包装器的领域,如果可能的话我真的想避免这种情况.