代码之家  ›  专栏  ›  技术社区  ›  Eloff

.NET AppDomains可以这样做吗?

  •  3
  • Eloff  · 技术社区  · 14 年前

    我花了好几个小时阅读AppDomain,但我不确定它们是否能像我希望的那样工作。

    如果我有两个类,AppDomain_1中的通用foo<t>和AppDomain_2中的bar:

    应用程序域1是应用程序。应用程序域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>被销毁?

    编辑 因此,删除了我的所有<gt;,手动将它们添加回。

    2 回复  |  直到 14 年前
        1
  •  6
  •   Hans Passant    14 年前

    你的问题中混合了类型和对象,这使得你很难回答。广告中的代码使用其他广告中也使用的类型没有问题,它只是加载程序集。但是一个广告有自己的垃圾收集堆,您不能直接引用另一个广告中的对象。它们需要跨广告边界序列化。是的,跨ipcchannel的远程处理可以做到这一点。

        2
  •  1
  •   Vagaus    14 年前

    如果您想跨应用程序域访问对象,这些对象需要从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);
        }
    }
    }
    

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

    希望这有帮助。