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

C反射:在解决方案中获取*所有*活动程序集?

  •  21
  • cyberconte  · 技术社区  · 15 年前

    我的问题是:

    我有两个项目——一个“公共”项目,其行为类似于带有各种支持代码的库,以及在许多调用中使用所述项目的实际程序。我们将这些项目称为“共同”和“计划”。它们都在同一个解决方案中。

    在“common”中,我有一个类用于普通反射任务,比如创建一个实例。如果我调用getExecutingAssembly,它会得到所有“公共”类型,但是当我使用getEntryAssembly时,会得到“程序”类型。

    虽然我当然可以编辑代码来处理2组ASM,但我担心解决方案中有2个以上的项目——比如5个(不知道为什么,但现在我们就到此为止),而且我担心调用getExecutingAssembly和getEntryAssembly不会获得整个程序中的所有类型。

    我还能做点什么把所有类型的 解决方案 ?

    4 回复  |  直到 12 年前
        1
  •  58
  •   bsneeze    15 年前
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    

    这将获取当前AppDomain中加载的所有程序集。

    如注释中所述,可以生成多个AppDomain,在这种情况下,每个AppDomain都可以有自己的程序集。这样做的直接好处是,可以通过卸载包含AppDomain的程序集来卸载程序集。

        2
  •  31
  •   3Dave    12 年前

    这是一个 真的? 旧问题,但为了将来参考,这里有一个完整的实现:

        public static IEnumerable<Assembly> GetAssemblies()
        {
            var list = new List<string>();
            var stack = new Stack<Assembly>();
    
            stack.Push(Assembly.GetEntryAssembly());
    
            do
            {
                var asm = stack.Pop();
    
                yield return asm;
    
                foreach (var reference in asm.GetReferencedAssemblies())
                    if (!list.Contains(reference.FullName))
                    {
                        stack.Push(Assembly.Load(reference));
                        list.Add(reference.FullName);
                    }
    
            }
            while (stack.Count > 0);
    
        }
    
        3
  •  7
  •   Tim Jarvis    15 年前

    另外:有些程序集不是直接加载的,因此您还应该在AppDomain的程序集加载事件上放置一个事件处理程序。

    AppDomain.CurrentDomain.AssemblyLoad += ....
    
        4
  •  7
  •   Gishu    15 年前

    怎么样 GetReferencedAssemblies 要处理assemblyRef元数据条目吗?“解决方案”不是CLR知道或关心的。它处理组装。

    private static List<Assembly> GetListOfEntryAssemblyWithReferences()
    {
      List<Assembly> listOfAssemblies = new List<Assembly>();
      var mainAsm = Assembly.GetEntryAssembly();
      listOfAssemblies.Add(mainAsm);
    
      foreach (var refAsmName in mainAsm.GetReferencedAssemblies())
      {
        listOfAssemblies.Add(Assembly.Load(refAsmName));
      }
      return listOfAssemblies;
    }
    

    Caveats:
    1。您仍然需要过滤核心组件系统。* 2。这只是在参考链的一个层次。但是可以递归地完成-使用更多的代码。