C#在解决方案中的所有项目中递归查找引用 [英] C# Recursively Find References in All Projects In Solution

查看:418
本文介绍了C#在解决方案中的所有项目中递归查找引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个非常大的解决方案(140个项目),我们将不同的项目部署到不同的服务器上.进行完整的部署是昂贵的(在时间上),因此,我们将尝试跟踪我们的更改,以确定哪些项目受更改影响,然后仅部署这些项目.

We have a very large solution (140ish projects) we deploy different projects to different servers. To do a complete deploy is costly (time-wise), so we will try to track our changes to determine what projects are affected by the change and then only deploy those projects.

例如:

比方说,我们有一个项目集成部分1"(IP1)和另一个集成部分2"(IP2).在IP2内,我们有一个Advert类,其中包含一个生成html链接的方法GenerateLink.广告中的另一个方法称为GenerateAd,称为GenerateLink.我修改了GenerateLink.

Let's say that we have a project "Integral Part 1" (IP1) and another "Intergral Part 2" (IP2). Inside IP2 we have a class, Advert, with a method that generates an html link, GenerateLink. GenerateLink is called by another method in Advert called, GenerateAd. I modify GenerateLink.

IP1呼叫并使用IP2中可用的服务.因此,将需要重新部署IP1,以使更改在IP1中可见.

IP1 calls into and uses the services available in IP2. Therefore IP1 will need to be redeployed in order for the changes to be visible in IP1.

这是一个简单的视图,但是应该解决这个问题.当前,我需要进入GenerateLink方法并找到所有引用,然后跟随每个引用并找到它们上的所有引用.我重复此过程,直到找到解决方案中所有项目的所有引用,这些引用以某种方式受到我的更改的影响.

This is a simplistic view, but should relate the issue. Currently, I need to go into the GenerateLink method and find all references, then follow each reference and find all references on them. I repeat this process until I have found all references across all projects within the solution that in some way are affected by my change.

是否有某种方法可以自动执行此过程,并且只需递归地为方法找到所有引用?

Is there some way to automate this process, and simply ask for all references, recursively, for a method?

我在搜索中找到的最接近的答案是在这里:以编程方式递归地找到对该函数的所有引用,但我认为这并不是我要找的东西.听起来更像是Visual Studio中已经存在的查找所有引用"工具.

The closest answer I've found in my searches is here: Programmatically find all references to a function recursively, but I don't think it's quite what I'm looking for. This sounds more like the find all references tool already in Visual Studio.

推荐答案

您可以使用RoslynMicrosoft.CodeAnalysis来实现此目的.您需要设置机器才能正常运行.

You can use Roslyn aka Microsoft.CodeAnalysis to achieve this. you need to setup the machine to work it out.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RoslynCompiler
{
    class ReferenceFinder
    {
        public void Find(string methodName)
        {

            string solutionPath = @"C:\Users\...\ConsoleForEverything.sln";
            var msWorkspace = MSBuildWorkspace.Create();

            List<ReferencedSymbol> referencesToMethod = new List<ReferencedSymbol>();
            Console.WriteLine("Searching for method \"{0}\" reference in solution {1} ", methodName, Path.GetFileName(solutionPath));
            ISymbol methodSymbol = null;
            bool found = false;

            //You must install the MSBuild Tools or this line will throw an exception.

            var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
            foreach (var project in solution.Projects)
            {
                foreach (var document in project.Documents)
                {
                    var model = document.GetSemanticModelAsync().Result;

                    var methodInvocation = document.GetSyntaxRootAsync().Result;
                    InvocationExpressionSyntax node = null;
                    try
                    {
                        node = methodInvocation.DescendantNodes().OfType<InvocationExpressionSyntax>()
                         .Where(x => ((MemberAccessExpressionSyntax)x.Expression).Name.ToString() == methodName).FirstOrDefault();

                        if (node == null)
                            continue;
                    }
                    catch(Exception exception)
                    {
                        // Swallow the exception of type cast. 
                        // Could be avoided by a better filtering on above linq.
                        continue;
                    }

                    methodSymbol = model.GetSymbolInfo(node).Symbol;
                    found = true;
                    break;
                }

                if (found) break;
            }

            foreach (var item in SymbolFinder.FindReferencesAsync(methodSymbol, solution).Result)
            {
                foreach (var location in item.Locations)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Project Assembly -> {0}", location.Document.Project.AssemblyName);
                    Console.ResetColor();
                }

            }

            Console.WriteLine("Finished searching. Press any key to continue....");
        }
    }
}

在运行示例之前,下载并安装以下项目:

Download and install following items before you run the sample:

.Net 4.6运行时

.net 4.6定位包

MSBuildTools 2015

需要以下设置来避免MSBuildWorkspace引发运行时异常 The type or namespace name 'MSBuild' does not exist in the namespace 'Microsoft.CodeAnalysis' (are you missing an assembly reference?) 因为nuget包中的程序集是建立在4.5.2之上的.

The following setup is required to avoid a runtime exception that MSBuildWorkspace Throws exception The type or namespace name 'MSBuild' does not exist in the namespace 'Microsoft.CodeAnalysis' (are you missing an assembly reference?) because the assembly in nuget package is built on 4.5.2.

创建一个针对.Net 4.6的控制台应用程序并安装nuget软件包: Microsoft.CodeAnalysis 1.0.0

Create a console application targeting .Net 4.6 and Install the nuget package: Microsoft.CodeAnalysis 1.0.0

上述代码的测试运行:

        ReferenceFinder finder = new ReferenceFinder();
        finder.Find("Read");

输出:

此程序可能需要更多增强,因为Roslyn的功能要强大得多.但这应该为您提供一个良好的开端.您可以探索有关Roslyn的更多信息,并且可以从C#代码中完全控制项目解决方案代码等.

This program might require more enhancment as Roslyn is much more powerful. But this should give you a head start. You can explore more about Roslyn and you can completely control your project solution code etc. from C# code.

待办事项:我将为此控制台应用程序创建一个github项目,并将很快更新此帖子.

这篇关于C#在解决方案中的所有项目中递归查找引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆