我花了好几个小时阅读AppDomains,但我不确定它们是否像我希望的那样工作。
如果我有两个类,通用Foo< T>在AppDomain#1中,AppDomain#2中的栏:
App Domain#1是应用程序。 App Domain#2就像一个插件,可以动态加载和卸载。
AppDomain#2想要创建Foo< Bar>并使用它。 FOO< T>在内部使用AppDomain#1中的许多类。
我不希望AppDomain#2使用带有反射的对象foo,我希望它使用Foo< Bar> foo,具有所有静态类型和编译速度。考虑到永远不会卸载包含Foo< T>的AppDomain#1,可以做到这一点吗?
如果是这样,当使用Foo< Bar>时,是否会在此处进行任何远程处理?
当我卸载AppDomain#2时,类型为Foo< Bar>被毁了?
修改我删除了所有<>,然后手动添加它们。
答案 0 :(得分:6)
您在问题中混合了类型和对象,这使得很难回答。 AD中的代码使用也在其他AD中使用的类型没有问题,它只是加载程序集。但是AD有自己的垃圾收集堆,你不能直接引用住在另一个AD中的对象。它们需要在AD边界上进行序列化。是的,通过IpcChannel进行远程处理将会这样做。
答案 1 :(得分:1)
如果要访问跨应用程序域的对象,这些对象需要从MarshalByRefObject继承;在这种情况下,你最终会得到一个真实对象的代理。这样可以安全地卸载应用程序域(如果您尝试通过代理调用,则会抛出异常)。
我想你想要完成的是:
using System;
using System.Reflection;
namespace TestAppDomain
{
class Program
{
static void Main(string[] args)
{
AppDomain pluginsAppDomain = AppDomain.CreateDomain("Plugins");
Foo foo = new Foo();
pluginsAppDomain.SetData("Foo", foo);
Bar bar= (Bar) pluginsAppDomain.CreateInstanceAndUnwrap(Assembly.GetEntryAssembly().FullName, typeof (Bar).FullName);
bar.UseIt();
AppDomain.Unload(pluginsAppDomain);
foo.SaySomething();
}
}
class Bar : MarshalByRefObject
{
public void UseIt()
{
Console.WriteLine("Current AppDomain: {0}", AppDomain.CurrentDomain.FriendlyName);
Foo foo = (Foo) AppDomain.CurrentDomain.GetData("Foo");
foo.SaySomething();
}
}
class Foo : MarshalByRefObject
{
public void SaySomething()
{
Console.WriteLine("Something from AppDomain: {0}", AppDomain.CurrentDomain.FriendlyName);
}
}
}
如果您的类型是在不同的程序集中定义的(可能),您可能会定义一个接口(在一个公共程序集中)并使类型实现此接口。
希望这有帮助。