简体   繁体   中英

Roslyn Get method invocation references in solution

I've created a very simple Solution with two projects inside it using .NET framework 4.6

TestReference.Data.dll

DataRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace TestReferences.Data
{
    public class DataRepository
    {
        public IEnumerable<string> GetProductNames()
        {
            return Enumerable.Repeat("Prod Name", 30);
        }

        public IEnumerable<int> GetProductIds()
        {
            return Enumerable.Range(12, 13);
        }
    }
}

ProductService.cs

using System.Collections.Generic;

namespace TestReferences.Data
{
    public class ProductService : IProductService
    {
        private readonly DataRepository dataRepository;

        public ProductService()
        {
            dataRepository = new DataRepository();
        }

        public IEnumerable<string> GetRecentProductNames()
        {
            return this.dataRepository.GetProductNames();
        }

        public IEnumerable<int> GetRecentProductIds()
        {
            return this.dataRepository.GetProductIds();
        }
    }
}

IProductService.cs

using System.Collections.Generic;

namespace TestReferences.Data
{
    public interface IProductService
    {
        IEnumerable<int> GetRecentProductIds();
        IEnumerable<string> GetRecentProductNames();
    }
}

TestReference.Web.dll

an MVC project that has a reference to the TestReference.Data.dll

HomeController.cs

using System.Web.Mvc;
using TestReferences.Data;

namespace TestReferences.Web.Controllers
{
    public class HomeController : Controller
    {
        IProductService productService;

        public HomeController()
        {
            this.productService = new ProductService();
        }

        public ActionResult Index()
        {
            this.productService.GetRecentProductIds();
            this.productService.GetRecentProductNames();

            return View();
        }

        public ActionResult About()
        {
            this.productService.GetRecentProductNames();

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

In that structure, if you open ProductService.cs and place the cursor over GetRecentProductNames then press shift + F12 it shows 2 results in TestReference.Web (Code-lens shows one more in the interface, only for Enterprise editions ). I've created another console application to get the same references.

public static void Main()
{
    MSBuildWorkspace ms =  MSBuildWorkspace.Create();
    Solution solution = ms.OpenSolutionAsync(@"D:\SampleApps\TestReferences\TestReferences.sln").Result;

    Document doc = solution
        .Projects
        .Where(p => p.Name == "TestReferences.Data")
        .SelectMany(p => p.Documents)
        .FirstOrDefault(d => d.Name == "ProductService.cs");

    if (doc == null)
    {
        throw new NullReferenceException("DOc");
    }

    SemanticModel model = doc.GetSemanticModelAsync().Result;

    List<MethodDeclarationSyntax> methodDeclarations = doc.GetSyntaxRootAsync().Result.DescendantNodes().OfType<MethodDeclarationSyntax>().ToList();

    // Method declaration is GetRecentProductNames()
    MethodDeclarationSyntax m = methodDeclarations.First();

    ISymbol symbolInfo = model.GetDeclaredSymbol(m);

    IEnumerable<ReferencedSymbol> references = SymbolFinder.FindReferencesAsync(symbolInfo, doc.Project.Solution).Result;
}

I receive two items inside the references , but their locations are 0.

[0] | GetRecentProductNames, 0 refs
[1] | GetRecentProductNames, 0 refs

It's my first touch with Roslyn and Microsoft.CodeAnalysis . The Version of the library is

<package id="Microsoft.CodeAnalysis" version="2.6.1" targetFramework="net46" />

GetDeclaredSymbol returns the associated symbol if its a declaration syntax node. This is not what you're looking for.

You should use GetSymbolInfo to get the symbol information about a syntax node:

var symbolInfo = semanticModel.GetSymbolInfo(m);
var references = SymbolFinder.FindReferencesAsync(symbolInfo, doc.Project.Solution).Result;

实际上,我试图实现与嵌入在Visual Studio 2017中的“ View Call Hierarchy ”相同的功能。只需右键单击方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM