2015-10-06 150 views
0

我们有一个非常大的解决方案(140个项目),我们将不同的项目部署到不同的服务器。要做完整的部署需要花费大量的时间,因此我们将尝试跟踪我们的变化,以确定哪些项目受到变更的影响,然后只部署这些项目。C#在解决方案中的所有项目中递归查找引用

例如:

比方说,我们有一个项目 “积分第1部分”(IP1)和另一个 “整数部分2”(IP2)。在IP2内部,我们有一个类Advert,其中有一个生成html链接的方法GenerateLink。 GenerateLink由广告中称为GenerateAd的另一种方法调用。我修改GenerateLink。

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

这是一个简单的观点,但应该涉及这个问题。目前,我需要进入GenerateLink方法并找到所有引用,然后按照每个引用并查找所有引用。我重复这个过程直到我发现解决方案中所有项目的所有引用在某种程度上都受到我的更改的影响。

是否有某种方法可以自动执行此过程,并简单地针对某个方法递归地请求所有引用?

我在我的搜索中发现的最接近的答案在这里:Programmatically find all references to a function recursively,但我不认为这是我正在寻找的。这听起来更像是在Visual Studio中已经找到所有引用工具。

+0

你有没有看到[这个问题](http://stackoverflow.com/questions/8750018/net-dll-references-dependency-checking-utility)?我想这可能会给你你想要的。 – DeadZone

+0

我会解决这个问题,而不是:_“做一个完整的部署是昂贵的(按时间)”_。您似乎要求将部署程序集的更新限制为那些您认为会在该环境中实际执行代码更改的程序。试图在逐个方法的基础上做到这一点似乎过于棘手,并可能导致诊断混乱。更好的做法是仅将这些程序集实际所需的环境部署到环境中,然后使用某种版本控制来决定在部署时更新哪些程序集。 –

+0

你如何部署这些应用程序?如果您正在寻找增量部署,那么您提出的解决方案可能会被杀死。如果您有完整构建的构建服务器设置,即使您可以确定从上次完整构建更改的程序集,也可以执行增量部署。 – vendettamit

回答

2

您可以使用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 runtime

.Net 4.6 targeting pack

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上。

创建控制台应用程序指定的.Net 4.6和安装NuGet包:

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

输出::

enter image description here

此程序 Microsoft.CodeAnalysis 1.0.0

的上面的代码测试运行因为Roslyn可能需要更多增强功能湖但这应该让你有一个良好的开端。您可以探索更多关于Roslyn的信息,您可以完全控制C#代码中的项目解决方案代码等。

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

+0

谢谢你的回应。事情变得疯狂了,但我会很快对它进行测试并做出回应。 – Saiori

相关问题