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

时间:2009-05-12 05:23:06

标签: c# reflection

继承我的问题:

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

在“Common”中,我有一个用于commo反射任务的类,比如创建一个实例。如果我调用GetExecutingAssembly,它会获得所有“公共”类型,但是当我使用GetEntryAssembly时,我会得到“程序”类型。

虽然我当然可以编辑代码以使用2套asm,但我担心解决方案中不仅仅有2个项目的情况 - 让我们说5(不知道为什么,但让我们只是现在去那里),我担心调用GetExecutingAssembly和GetEntryAssembly不会获得整个程序中的所有类型。

我可以采取其他措施来获取解决方案中的所有类型吗?

4 个答案:

答案 0 :(得分:58)

Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

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

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

答案 1 :(得分:35)

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

    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);

    }

答案 2 :(得分:9)

另外:某些程序集不会立即加载,因此您还应该在AppDomain的程序集加载事件上放置一个事件处理程序。

AppDomain.CurrentDomain.AssemblyLoad += ....

答案 3 :(得分:8)

GetReferencedAssemblies如何处理AssemblyRef元数据条目? “解决方案”不是CLR知道或关心的东西......它在Assemblies中处理。

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;
}

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

相关问题