日期:2014-05-18  浏览次数:20799 次

在.net中,如何获取当前程序域AppDomain.CurrentDomain中的其它程序集的运行时的某个对象实例?
我要做一个插件引擎,用到一些反射的机制,但是在获取当前程序域AppDomain.CurrentDomain中的其它程序集中的运行时对象时,不知道怎么获得,想了很久没有头绪,请大侠们不吝赐教!谢谢!

------解决方案--------------------
跨Appdomain读取对象时,好像要封送,对象可序列化或者实现MarshalByRefObject类。
------解决方案--------------------
可以参考clr via C#的Appdomain这一章,里面有详细介绍跨Appdomain读取运行时对象。
------解决方案--------------------
类似这样,加载程序集->反射得出类型—>操作:
C# code
internal static class ExceptionTree {
   public static void Go() {
      // Explicitly load the assemblies that we want to reflect over
      LoadAssemblies();

      // Recursively build the class hierarchy as a hyphen-separated string
      Func<Type, String> ClassNameAndBase = null;
      ClassNameAndBase = t => "-" + t.FullName +
          ((t.BaseType != typeof(Object)) ? ClassNameAndBase(t.BaseType) : String.Empty);

      // Define our query to find all the public Exception-derived types in this AppDomain's assemblies
      var exceptionTree =
          (from a in new[] { typeof(Exception).Assembly } // AppDomain.CurrentDomain.GetAssemblies()
           from t in a.GetExportedTypes()
           where t.IsClass && t.IsPublic && typeof(Exception).IsAssignableFrom(t)
           let typeHierarchyTemp = ClassNameAndBase(t).Split('-').Reverse().ToArray()
           let typeHierarchy = String.Join("-", typeHierarchyTemp, 0, typeHierarchyTemp.Length - 1)
           orderby typeHierarchy
           select typeHierarchy).ToArray();

      // Display the Exception tree
      Console.WriteLine("{0} Exception types found.", exceptionTree.Length);
      foreach (String s in exceptionTree) {
         // For this Exception type, split its base types apart
         String[] x = s.Split('-');

         // Indent based on # of base types and show the most-derived type
         Console.WriteLine(new String(' ', 3 * (x.Length - 1)) + x[x.Length - 1]);
      }
   }


   private static void LoadAssemblies() {
      String[] assemblies = {
            "System,                    PublicKeyToken={0}",
            "System.Core,               PublicKeyToken={0}",
            "System.Data,               PublicKeyToken={0}",
            "System.Design,             PublicKeyToken={1}",
            "System.DirectoryServices,  PublicKeyToken={1}",
            "System.Drawing,            PublicKeyToken={1}",
            "System.Drawing.Design,     PublicKeyToken={1}",
            "System.Management,         PublicKeyToken={1}",
            "System.Messaging,          PublicKeyToken={1}",
            "System.Runtime.Remoting,   PublicKeyToken={0}",
            "System.Security,           PublicKeyToken={1}",
            "System.ServiceProcess,     PublicKeyToken={1}",
            "System.Web,                PublicKeyToken={1}",
            "System.Web.RegularExpressions, PublicKeyToken={1}",
            "System.Web.Services,       PublicKeyToken={1}",
            "System.Windows.Forms,      PublicKeyToken={0}",
            "System.Xml,                PublicKeyToken={0}",
         };

      String EcmaPublicKeyToken = "b77a5c561934e089";
      String MSPublicKeyToken = "b03f5f7f11d50a3a";

      // Get the version of the assembly containing System.Object
      // We'll assume the same version for all the other assemblies
      Version version = typeof(System.Object).Assembly.GetName().Version;

      // Explicitly load the assemblies that we want to reflect over
      foreach (String a in assemblies) {
         String AssemblyIdentity =
            String.Format(a, EcmaPublicKeyToken, MSPublicKeyToken) +
               ", Culture=neutral, Version=" + version;
         Assemb