如何以编程方式获取类依赖项及其各自的文件位置?

2024-04-02

我需要获得给定项目的类之间的某种依赖关系图,即该特定类使用的所有类。我想知道给定的类正在使用哪些类,以便以后可以在项目中找到它们的文件路径。考虑以下简单示例:

public class Dog: Animal, IBark
{
    public void Bark()
    {
        // Code to bark.
    }

    public void Fight(Cat cat)
    {
        // Code to fight cat.
    }
}

对于这个具体的例子,我想知道哪些类Dog类用途。所以我想以编程方式访问具有这些依赖项的对象。在这种情况下,该对象将包含IBark, Animal and Cat类/接口以及可能它们各自的文件路径。

这在 C# 中可能吗?我尝试研究 Roslyn API,虽然我可以解析文档并遍历它来查找节点,但我还没有找到一种方法来获取与这些节点相关的元数据,这些元数据可能会给我我正在寻找的内容(例如文件路径) 。这让我想知道是否有更好的方法来解决这个问题。


这可以通过以下方式完成Roslyn蜜蜂。算法如下:

  1. 加载解决方案 (.sln)
  2. 迭代项目 (.csproj)
  3. 迭代项目内的文档 (.cs)
  4. Load semantic model对于文档
  5. Get SyntaxTree并遍历所有SyntaxNode
  6. 检测每个SyntaxNode具体类型。如果检测到的语法是类定义(比方说 Dog) - 继续遍历,考虑到进一步检测到的类或接口依赖于 Dog

下面的示例代码。我也犯了这个github https://github.com/amikulich/ArchitectureGuards。您将会感兴趣单元测试样本 https://github.com/amikulich/ArchitectureGuards/tree/master/ArchitectureGuards/ArchitectureGuards.Tests/DependencyGraph and 基于您的示例的示例解决方案 https://github.com/amikulich/ArchitectureGuards/tree/master/Samples/DependencyGraph/SampleProject1ForDependencyGraph。我假设单个文件仅包含一个类定义,但是我认为这应该足以让您开始。

        var dependencies = new Dictionary<string, List<string>>(); 
        //key - class name, value - list of dependent class names

        var project = workspace.CurrentSolution.Projects.First();

        foreach (var document in project.Documents)
        {
            var semanticModel = await document.GetSemanticModelAsync();
            KeyValuePair<string, List<string>>? keyValue = null;

            foreach (var item in semanticModel.SyntaxTree.GetRoot().DescendantNodes())
            {
                switch (item)
                {
                    case ClassDeclarationSyntax classDeclaration:
                    case InterfaceDeclarationSyntax interfaceDeclaration:
                        if (!keyValue.HasValue)
                        {
                            keyValue = new KeyValuePair<string, List<string>>(semanticModel.GetDeclaredSymbol(item).Name, new List<string>());
                        }
                        break;
                    case SimpleBaseTypeSyntax simpleBaseTypeSyntax:
                        keyValue?.Value.Add(simpleBaseTypeSyntax.Type.ToString());
                        break;
                    case ParameterSyntax parameterSyntax:
                        keyValue?.Value.Add(parameterSyntax.Type.ToString());
                        break;
                }
            }

            if (keyValue.HasValue)
            {
                dependencies.Add(keyValue.Value.Key, keyValue.Value.Value);
            }
        }

对于上面的代码,工作区是通过以下方式加载的:

var workspace = MSBuildWorkspace.Create();
await workspace.OpenSolutionAsync(solutionFilePath);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何以编程方式获取类依赖项及其各自的文件位置? 的相关文章

随机推荐

  • 如何从 GAC 加载程序集?

    我正在尝试使用 Assembly Load 加载 GAC 中的程序集 例如 假设我想列出存在于的所有类型演示核心 dll 我该如何加载演示核心 dll 当我尝试这个时 Assembly a Assembly Load Presentatio
  • MUI:如何以编程方式删除 DataGrid 中选定的行?

    我正在使用 MUI 创建文件列表DataGrid 用户可以选中复选框DataGrid做出他们的选择 我希望在用户执行某些操作 例如删除所选文件 后重置该复选框 我面临的问题是在执行删除操作后 该复选框仍然在同一位置被选中 例如 在我按下删除
  • 更改搜索栏拇指的大小

    我正在使用可绘制的搜索栏拇指 android thumb drawable thumb 我怎样才能设置这个拇指的大小dip单元 因为我使用类似搜索栏的样式 我想要拇指12dip高度和宽度 对我来说设置拇指大小的最灵
  • org.springframework.beans.factory.BeanCreationException:创建类路径资源中定义的名称为“scriptDataSourceInitializer”的bean时出错?

    我是学习 Spring Boot Web 的新手 我已经开始学习 spring jpa 数据 我使用 h2 数据库 我想使用插入测试数据 org springframework beans factory BeanCreationExcep
  • 仅显示 SQL 查询的前 N ​​行输出

    有没有办法只显示前 N 行输出SQL query 如果查询停止运行一次 则奖励积分N输出行 我最感兴趣的是找到适用于的东西Oracle 如果您指定您的目标数据库将会很有帮助 不同的数据库有不同的语法和技术来实现这一点 例如 在 Oracle
  • Git:如何排除存储库中的子文件夹?

    我已经在我的项目的文件夹中创建了一个存储库 你知道 git init 我有Webstorm文件夹 idea另一个与此无关的文件夹 我对保留在存储库中不感兴趣 并且我不希望此文件夹显示为要添加的新文件 我想忘记这些子文件夹 如何在提交整个存储
  • vertx 内的多线程

    我是 vert x 的新手 我正在尝试 vert x NetServer 功能 http vertx io core manual java html writing tcp servers and clients http vertx i
  • 下载 Fuchsia 源代码 - Jiri 钩子由于更新项目或包时出现致命错误而未运行

    Per 获取紫红色源代码 https fuchsia dev fuchsia src development source code echo PATH media cwh 32GB swdev fuchsia jiri root bin
  • 如何在 SQLite 中拥有自动时间戳?

    我有一个 SQLite 数据库版本 3 我正在使用 C 创建一个使用该数据库的应用程序 我想在表中使用时间戳字段来实现并发 但我注意到当我插入新记录时 该字段未设置 并且为空 例如 在 MS SQL Server 中 如果我使用时间戳字段
  • OpenCV 使用 k 均值对图像进行色调分离

    我想在 C 接口 cv 命名空间 中使用 k means 和 OpenCV 对图像进行色调分离 但得到了奇怪的结果 我需要它来减少一些噪音 这是我的代码 include cv h include highgui h using namesp
  • 在 AngularJS 中下载 zip 文件

    尝试在 AngularJS 中下载 zip 文件 我查看了AngularJS 从服务器下载pdf文件 https stackoverflow com questions 25490007 angularjs download pdf fil
  • 按时间间隔分组

    我需要将我的表分组为 15 分钟的间隔 我可以这样做 select dateadd minute datediff minute 0 ts 15 15 0 sum goodpieces from StationCount Group by
  • 在mongodb中查找按距离排序的LineString附近的点

    我有一组代表街道 黑线 的点和代表地图上某个地点的点 红点 我想找到指定街道附近的所有点 按距离排序 我还需要能够指定最大距离 蓝色和绿色区域 这是一个简单的例子 我想用 near运算符 但它只接受Point作为输入 而不是LineStri
  • 如何确定您是否使用不带 $_SERVER['HTTPS'] 的 HTTPS

    我在网上看到很多教程说你需要检查 SERVER HTTPS 如果服务器连接受 HTTPS 保护 我的问题是在我使用的一些服务器上 SERVER HTTPS 是一个未定义的变量 会导致错误 我可以检查是否还有另一个应该始终定义的变量 需要明确
  • NSExtensionRequestHandling 不处理本机消息

    我正在尝试为我的本机应用程序创建 Safari Web 扩展 我想要一个带有按钮的弹出窗口 单击该按钮将与我的本机应用程序进行通信 在开始这部分之前 我在发送本机消息并在其中处理它时遇到了问题beginRequest类中的函数符合NSExt
  • 如何确定 UIWebView 的内容大小?

    我有一个UIWebView具有不同的 单页 内容 我想了解一下CGSize内容以适当调整我的父母视图的大小 显而易见的 sizeThatFits 不幸的是只返回 webView 的当前帧大小 事实证明 我的第一个猜测是使用 sizeThat
  • 使用继承时出现重复的外键

    我创建了这些类 以便通过 EntityFramework 6 代码优先方法生成数据库模型 public class Vehicle public long Id get set public long ResponsiblePersonId
  • 卡兹马兹动画

    我正在寻求帮助 我想在 Matlab 上为 Kaczmarz 方法制作动画 它的方法允许通过在超平面上的串行投影解向量来找到方程组的解 该解向量由系统方程组给出 我想制作该矢量移动的动画 就像该点在投影矢量上一样 System of equ
  • Joomla 3.2.3 精选文章排序

    在 Joomla 3 2 3 中 我无法像 J 1 5 x 那样进行文章排序 我想让首页文章排序像我在管理员区域中定义的那样 我尝试了几种方法 但仍然没有任何成功 已经 1 周了 我最后一次尝试的是这样的 a Content gt Feat
  • 如何以编程方式获取类依赖项及其各自的文件位置?

    我需要获得给定项目的类之间的某种依赖关系图 即该特定类使用的所有类 我想知道给定的类正在使用哪些类 以便以后可以在项目中找到它们的文件路径 考虑以下简单示例 public class Dog Animal IBark public void