How to get metadata of classes without compiling the project
Asked Answered
A

2

8

In our project we use a lot of T4 code generation. We use an ORM called DataObjects.Net of X-Tensive. We have a bit a chicken-egg problem. We need to compile the classes of the ORM before we can use the assembly's metadata to generate code. Then when the code is generated we can compile the model again but now in combination with generated code (partial classes). Most of the custom code in the model classes can not be compiled without the generated code.

How we solved it is to have a separate configuration in VS2013 called 'Model'. In this configuration a 'Conditional compilation symbol' call 'JUSTMODEL' is present. All code that does not compile without the generated code is placed between #if !JUSTMODEL #endif compiler directives which causes this code not be compiled for the 'Model' configuration.

This is a bit tedious. We have created a little extensiblity application that automates this proces but it more and more becomes pretty time consuming to run the proces.

Now I was wondering if it is possible to get the metadata of the Model assembly without building the assembly via an extensibility API of some kind. I see lots of tools in Visual Studio that understand classes loaded in the editors and give me some feedback (like intellisense).

Appressed answered 15/3, 2014 at 15:12 Comment(8)
If you're willing to wait a bit, you might want to consider using Roslyn once it comes out. I wouldn't worry about using the CTP from 2012 as it's pretty outdated. Matthieu Mezil has been doing some similar work and posting on T4 with Roslyn which you might find helpful.Cd
Ah, Roslyn, I've been waiting for ever for that to come. It would defenitly solve this problem (and others).Appressed
Could I somehow use the Intellisense Database to achieve what I want?Appressed
Have you looked at ILSpy? It obviously has a different intention than you do, but it it does have a distinct module just for type and member definitions. It could be a good start.Spermatocyte
No, I don't think that will help me. ILSpy needs assemblies to be able to browse/decompile. What I need is the oposite. I would like to know information about classes/members before compilationAppressed
Oh! My mistake, I thought you were reversing the workflow. In that case, you might want the parent project, SharpDevelop, which seems to start parsing the assemblies here.Spermatocyte
You could use one of C# Parser projects listed in https://mcmap.net/q/190579/-which-parsers-are-available-for-parsing-c-code-closedRiancho
@Tapeshvar --- ridiculous edit. Your single edit of a '?' turns the title into nonsense. It was grammatically correct before your edit. Please rollback and stop angling for a badge.Razorbill
A
7

There is an even better way than NRefactor. I've discovered the CodeModel inside Visual Studio. It gives me all the metadata I need to generate our code. You can find a lot of details on how to achieve that on the net like here:

  1. Microsoft
  2. Tangible

and many other places. The coding is a bit different than in C# because of the dynamic nature of the data but when you get the hang of it, it's quite easy and very powerfull.

Appressed answered 25/3, 2014 at 7:13 Comment(0)
C
2

I would consider using NRefactory library or similar. The idea of NRefactory is similar to Roslyn so should solve you problem. If I understand you correctly you need information about classes and their members before compilation. The simplest code based on NRefactory, responsible for retrieving list of classes together with information about methods and properties, could look in the following way:

var parser = new CSharpParser();
var syntaxTree = parser.Parse(code);

var classes = syntaxTree.Descendants.OfType<TypeDeclaration>().Where(x => x.ClassType == ClassType.Class);
foreach (var typeDeclaration in classes)
{
    var result = typeDeclaration.Descendants.Where(d => d is MethodDeclaration || d is PropertyDeclaration);
    foreach (var declaration in result )
    {
        //...
    }
}

This example performs only syntax analysis of the source code. However, you can also perform semantic analysis with NRefactory by using CSharpAstResolver class.

Choreography answered 23/3, 2014 at 15:10 Comment(1)
Yep, that is what I am looking for. It looks promising. My dilemma now is wait for Roslyn or go ahead with NRefactor. My guess is that as soon as Roslyn becomes available, initiatives like NRefactor will slowly disappear. We already have a library that disects the compiled assembly but that gives too many problems during compilation (and lots of conditional code). Thanks for your suggestion Michal.Appressed

© 2022 - 2024 — McMap. All rights reserved.