C# 反射:在解决方案中获取*所有*活动程序集?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/851248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Reflection: Get *all* active assemblies in a solution?
提问by cyberconte
Heres my problem:
这是我的问题:
I have 2 projects - one 'common' projects with acts like a library with all kinds of support code, and the actual program that uses said project in many of its calls. We'll call these projects "Common" and "Program". They are both in the same solution.
我有 2 个项目 - 一个“常见”项目,其行为类似于具有各种支持代码的库,以及在许多调用中使用所述项目的实际程序。我们将这些项目称为“Common”和“Program”。他们都在同一个解决方案中。
Within "Common", I have a class for commo reflection tasks, like creating an instance. If I call GetExecutingAssembly, it gets all the "Common" Types, however when I use GetEntryAssembly I get the "Program" types.
在“Common”中,我有一个用于常见反射任务的类,比如创建一个实例。如果我调用 GetExecutingAssembly,它会获取所有“通用”类型,但是当我使用 GetEntryAssembly 时,我会获取“程序”类型。
While I certainly could edit the code to work with 2 sets of asm, I'm afraid of a situation where there are more than just 2 projects in the solution - lets say 5 (don't know why, but lets just go there for now), and I'm afraid that calling GetExecutingAssembly and GetEntryAssembly will not get all the Types in the entire program.
虽然我当然可以编辑代码以使用 2 组 asm,但我担心解决方案中不止 2 个项目的情况 - 比如说 5 个(不知道为什么,但让我们去那里看看现在),恐怕调用 GetExecutingAssembly 和 GetEntryAssembly 不会获得整个程序中的所有类型。
Is there something else that i can do to get all the Types in a solution?
我还能做些什么来获得解决方案中的所有类型?
采纳答案by bsneeze
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
This will get all of the loaded assemblies in the current AppDomain.
这将获取当前 AppDomain 中所有加载的程序集。
As noted in the comments, it's possible to spawn multiple AppDomains, in which case each can have its own assemblies. The immediate advantage to doing so is that you can unload Assemblies by unloading the containing AppDomain.
如评论中所述,可以生成多个 AppDomain,在这种情况下,每个 AppDomain 都可以拥有自己的程序集。这样做的直接好处是您可以通过卸载包含的 AppDomain 来卸载程序集。
回答by Gishu
How about GetReferencedAssembliesto work off the AssemblyRef metadata entries? The 'solution' is not something that the CLR knows or cares about.. it deals in Assemblies.
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. You still need to filter core assemblies System.*
2. This just goes one level deep in the ref chain.. but can be done recursively - with more code.
注意事项:
1. 您仍然需要过滤核心程序集 System.* 2. 这只是在引用链中深入一层......但可以递归完成 - 使用更多代码。
回答by Tim Jarvis
Also: Some assemblies are not loaded straight away, so you should also put an Event Handler on the AppDomain's assembly load event.
另外:有些程序集不会立即加载,因此您还应该在 AppDomain 的程序集加载事件上放置一个事件处理程序。
AppDomain.CurrentDomain.AssemblyLoad += ....
回答by 3Dave
This is a reallyold question, but for future reference here's a complete implementation:
这是一个非常古老的问题,但为了将来参考,这里有一个完整的实现:
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);
}