从通过MSBuildWorkspace获得的解决方案获得Project p,是否可以获得该项目的详细信息MetadataReferences(在这种情况下它是一个.dll),例如类和方法?
答案 0 :(得分:1)
我找到了一种通过Micrososoft.CodeAnalysis Symbol Api获取类和方法的方法,它非常受到msdn博客中Kevin Pilch-Bisson帖子的启发。
private void GetSymbolsTest(ref Project project, ref MetadataReference metaRef)
{
if (!project.MetadataReferences.Contains(metaRef))
throw new DllNotFoundException("metadatarefence not in project");
var compilation = project.GetCompilationAsync().Result;
var metaRefName = Path.GetFileNameWithoutExtension(metaRef.Display);
SymbolCollector symCollector = new SymbolCollector();
symCollector.Find(compilation.GlobalNamespace, metaRefName);
Console.WriteLine($"Classes found: {symCollector.Classes.Count}");
Console.WriteLine($"Methods found: {symCollector.Methods.Count}");
}
public class SymbolCollector
{
public HashSet<IMethodSymbol> Methods { get; private set; } = new HashSet<IMethodSymbol>();
public HashSet<INamedTypeSymbol> Classes { get; private set; } = new HashSet<INamedTypeSymbol>();
public void Find(INamespaceSymbol namespaceSymbol, string assemblyRefName)
{
foreach (var type in namespaceSymbol.GetTypeMembers())
{
if (String.Equals(type.ContainingAssembly.Name, assemblyRefName, StringComparison.CurrentCultureIgnoreCase))
Find(type);
}
foreach (var childNs in namespaceSymbol.GetNamespaceMembers())
{
Find(childNs, assemblyRefName);
}
}
private void Find(INamedTypeSymbol type)
{
if (type.Kind == SymbolKind.NamedType)
Classes.Add(type);
foreach (var member in type.GetMembers())
{
if (member.Kind == SymbolKind.Method)
Methods.Add(member as IMethodSymbol);
}
foreach (var nested in type.GetTypeMembers())
{
Find(nested);
}
}
}
这样我就不需要使用System.Reflection。希望它能帮到某个人。
答案 1 :(得分:1)
在项目中,调用GetCompilationAsync()以获取编译。从那里,您可以查看GlobalNamespace属性,该属性为您提供全局命名空间,您可以在其中从代码中走到子命名空间和类型,并将所有引用合并在一起。如果你想在特定的引用中遍历类型,你可以调用GetAssemblyOrModuleSymbol给它一个特定的元数据引用,然后你也可以从那里走。
答案 2 :(得分:0)
foreach (var mRef in project.MetadataReferences)
{
Type[] assemblyTypes;
if (!File.Exists(mRef.Display))
continue;
try
{
assemblyTypes = Assembly.ReflectionOnlyLoadFrom(mRef.Display)
.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
assemblyTypes = e.Types
.Where(type => type != null)
.ToArray();
}
// ....
}