We are using Roslyn Compiler for generating a Dependency Graph for a given application code. The application code can span across multiple solutions and can have references between the solutions (ex. Service code in one solution, common business logic in another solution etc.)
For the purpose of generating the Dependency Graph, we would require fully-qualified name and exact path of all the custom types refereed (ones which we have created as our application code).
Roslyn happens to give this information using the SemanticModel's Symbol Information.
Scenario which works:
SemanticModel's Symbol Information gives the Location (path) and ContainingSymbol information for any Type if the type is declared in the same Solution (under some project) in which it is getting used.
Scenario which does not work:
If the refereed Type is not part of the current solution but is part of some other solution which is getting refereed in the existing solution, then the SemanticModel does not give any Symbol Information which can give the Path and Fully Qualified Name.
Note:
- We have already tried using the variants of GetSpeculativeSymbolInfo and GetSpeculativeTypeInfo. But it does not give any information. It just mentions that its a part of MetaData (as if we are using a Type from .NET Class Lib).
- Following link "Get fully-qualified metadata name in Roslyn" gives a direction; but the approach does not work in the context of cross solution references.
- Have refereed following link: "Roslyn: get the symbol for a type defined in a third-party library". But this is not working as well (or may be we are missing on some thing simple). We were trying to explore the option of using Compilation.GetTypeByMetadataName().
Looking forward to some pointers from the Experts.
EDIT: Further details
//Sample Code for Testing
public class TestClass
{
Student student = new Student();
Person person = new Person();
}
public class Student
{
public string Name { get; set; }
}
Notes:
- TestClass is part of project Project_1 which is in Solution_1.
- TestClass has two members:
Class Student is part of project Project_2 which is in Solution_1 and Project_1 has a Project Reference to Project_2.
Class Person is part of project Project_XYZ which is in Solution_XYZ and Project1 from Solution_1 has a dll Reference to Project_XYZ from Solution Solution_XYZ.
The .dll of Project_XYZ is getting created at location "..\Projects\SourceCode\AllBinaries" and "Project_1" from Solution_1 refers the .dll of Project_XYZ from this location "..\Projects\SourceCode\AllBinaries"
Code for getting Symbol Information of the Type:
private void GetSymbolDetails(TypeSyntax typeSyntax)
{
ISymbol symbol = semanticModel.GetSymbolInfo(typeSyntax).Symbol;
//HERE semanticModel = document.GetSemanticModelAsync().Result;
}
Scenario which works:
When the above code is called with input parameter as "IdentifierNameSyntax IdentifierName Student", the "symbol" gives all the required symbol details of "Student" (including fully-qualified name and exact path).
Scenario which does not work:
When the above code is called with input parameter as "IdentifierNameSyntax IdentifierName Person", the "symbol" value is null.
Hope I was able to give a better overview of my problem. Looking forward to further updates.