.NET AppDomains可以这样做吗?

时间:2010-05-31 17:07:57

标签: c# .net

我花了好几个小时阅读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>被毁了?

修改我删除了所有<>,然后手动添加它们。

2 个答案:

答案 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);
    }
}
}

如果您的类型是在不同的程序集中定义的(可能),您可能会定义一个接口(在一个公共程序集中)并使类型实现此接口。

希望这有帮助。