本帖最后由 间谍 于 2010-09-17 06:04:08 编辑

解决方案 »

  1.   

    一个应用程序域可以通过两种方式和另一个应用程序域进行通信。一种是传值(by value),另一种是传引用(by reference)
    传值是通过对象的序列和反序列实现的,因此要传递的对象必须有 System.Serializable属性.
    它的实现原理:我们在应用程序域A中构造了一个对象A1,现在要将对象A1的引用传递给另
    一个应用程序域B,CLR首先会将对象A1的字段序列化到一个内存块,然后再将这个内存块的地址
    传递给另一应用程序域B,将由应用程序域B反序列化得对新的对象B1,因此这个新的对象B1应该是在
    应用程序域A中。
    可以通过以下代码来证实:
    using System;
    using System.Reflection;
    using System.Threading;
    using System.Runtime.Serialization;class App {
    static void Main() {
    AppDomain domain = AppDomain.CreateDomain("MyNewDomain", null, null);Test test = (Test) domain.CreateInstanceAndUnwrap(
    Assembly.GetCallingAssembly().FullName, "Test");test.TestMethod(Thread.GetDomain().FriendlyName);
    AppDomain.Unload(domain);
    }
    }[Serializable]
    class Test// : MarshalByRefObject
    {
    public void TestMethod(string srcAppDomain) {
    Console.WriteLine(
    "Code from the '{0}' AppDomain\n" +
    "called into the '{1}'. AppDomain.",
    srcAppDomain, Thread.GetDomain().FriendlyName);
    }
    }而传引用则能过创建代理对象来实现,传递的对象要从System.MarshalByRefObject类继承。
    当对象的引用传递到另一应用程序域中时,CLR会在目的应用程序域中创建一个代理对象,
    目的应用程序域中引用的将是这个代理对象,它通过代理对象来调用源应用程序域中的对象。
    由于它实际上调用的还是源应用程序域中的对象,因此线程要在两个应用程序域中跳转。
    (参见.NET框架程序设计(修订版)P514)可以修改上面Test类部分代码来证实:
    // [Serializable]
    class Test : MarshalByRefObject
      

  2.   

    http://msdn.microsoft.com/zh-cn/library/system.marshalbyrefobject.aspx
      

  3.   

    问题简化一下,其实是两个问题。首先,比如我有两个Assembly,分别是Main和Plugin现在我想让Main动态的加载Plugin,在Plugin中生成类,调用方法,而且可以随时卸载。最简单的我想是在Main直接加载Plugin,但.Net不支持卸载Assembly(?),这样就无法实现我随时卸载的需求。然后我自然就想到创建一个新的Appdomain,然后用新的appdomain加载Plugin,然后从Main访问新appdomain中的类,不需要的时候只要卸掉那个appdomain。但因为Main所在的appdomain在调用时需要关于plugin的metadata,所以clr又要把plugin加载到main所在的appdomain中,这样的话就达不到我想要的了,这样的情况下,我应该怎么办?(第一个疑問)通过这个问题,又引出我主题里的疑問,那个by val方式在本机的appdomaiin之间应用时有意义吗?为什么不直接加载class所在的assembly呢?(第二个疑問)