您可以使用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");
输出::
此程序 Microsoft.CodeAnalysis 1.0.0
的上面的代码测试运行因为Roslyn
可能需要更多增强功能湖但这应该让你有一个良好的开端。您可以探索更多关于Roslyn
的信息,您可以完全控制C#代码中的项目解决方案代码等。
待办事项:我将为此控制台应用程序创建一个github项目,我将尽快更新此帖。
你有没有看到[这个问题](http://stackoverflow.com/questions/8750018/net-dll-references-dependency-checking-utility)?我想这可能会给你你想要的。 – DeadZone
我会解决这个问题,而不是:_“做一个完整的部署是昂贵的(按时间)”_。您似乎要求将部署程序集的更新限制为那些您认为会在该环境中实际执行代码更改的程序。试图在逐个方法的基础上做到这一点似乎过于棘手,并可能导致诊断混乱。更好的做法是仅将这些程序集实际所需的环境部署到环境中,然后使用某种版本控制来决定在部署时更新哪些程序集。 –
你如何部署这些应用程序?如果您正在寻找增量部署,那么您提出的解决方案可能会被杀死。如果您有完整构建的构建服务器设置,即使您可以确定从上次完整构建更改的程序集,也可以执行增量部署。 – vendettamit