簡體   English   中英

C#在解決方案中的所有項目中遞歸查找引用

[英]C# Recursively Find References in All Projects In Solution

我們有一個非常大的解決方案(140個項目),我們將不同的項目部署到不同的服務器上。 進行完整的部署是昂貴的(按時),因此,我們將嘗試跟蹤更改以確定哪些項目受更改影響,然后僅部署這些項目。

例如:

假設我們有一個項目“集成部分1”(IP1)和另一個“集成部分2”(IP2)。 在IP2內,我們有一個Advert類,它帶有一個生成html鏈接的方法GenerateLink。 AdvertLink由廣告中的另一個方法GenerateAd調用。 我修改了GenerateLink。

IP1呼叫並使用IP2中可用的服務。 因此,將需要重新部署IP1,以使更改在IP1中可見。

這是一個簡單的視圖,但應與問題相關。 當前,我需要進入GenerateLink方法並找到所有引用,然后跟隨每個引用並找到它們上的所有引用。 我重復此過程,直到找到解決方案中所有項目的所有引用,這些引用以某種方式受到我的更改的影響。

是否有某種方法可以自動執行此過程,並簡單地遞歸地要求所有方法的引用?

我在搜索中找到的最接近的答案是:以編程方式遞歸地找到對函數的所有引用 ,但是我認為這並不是我要找的東西。 這聽起來更像是Visual Studio中已經存在的“查找所有引用”工具。

您可以使用Roslyn (也稱為Microsoft.CodeAnalysis來實現此目的。 您需要設置機器才能正常工作。

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....");
        }
    }
}

在運行示例之前,請下載並安裝以下項目:

.NET 4.6運行時

.NET 4.6目標包

MSBuildTools 2015

為了避免運行時異常MSBuildWorkspace引發異常,需要以下設置,因為nuget程序包中的程序集是內置的, MSBuildWorkspace The type or namespace name 'MSBuild' does not exist in the namespace 'Microsoft.CodeAnalysis' (are you missing an assembly reference?)在4.5.2。

創建一個針對.Net 4.6的控制台應用程序並安裝nuget包: Microsoft.CodeAnalysis 1.0.0

上面代碼的測試運行:

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

輸出:

在此處輸入圖片說明

由於Roslyn功能更強大,因此該程序可能需要更多增強。 但這應該為您提供一個開端。 您可以探索有關Roslyn更多信息,並且可以從C#代碼完全控制項目解決方案代碼等。

待辦事項:我將為此控制台應用程序創建一個github項目,我將盡快更新此帖子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM