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).

Zane
  • 4,129
  • 1
  • 21
  • 35
Paul Sinnema
  • 2,534
  • 2
  • 20
  • 33
  • 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](http://msmvps.com/blogs/matthieu/archive/2011/10/19/invokeactivity-using-t4.aspx) which you might find helpful. – Jim Wooley Mar 19 '14 at 16:47
  • Ah, Roslyn, I've been waiting for ever for that to come. It would defenitly solve this problem (and others). – Paul Sinnema Mar 20 '14 at 06:58
  • Could I somehow use the Intellisense Database to achieve what I want? – Paul Sinnema Mar 22 '14 at 08:09
  • Have you looked at [ILSpy](http://ilspy.net/)? It obviously has a different intention than you do, but it it does have a [distinct module](https://github.com/icsharpcode/ILSpy/blob/master/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs) just for type and member definitions. It could be a good start. – John C Mar 22 '14 at 22:45
  • 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 compilation – Paul Sinnema Mar 23 '14 at 10:23
  • Oh! My mistake, I thought you were reversing the workflow. In that case, you might want the parent project, [SharpDevelop](http://www.icsharpcode.net/OpenSource/SD/), which seems to start parsing the assemblies [here](https://github.com/icsharpcode/SharpDevelop/blob/master/src/Main/SharpDevelop/Parser/AssemblyParserService.cs). – John C Mar 23 '14 at 14:43
  • You could use one of C# Parser projects listed in http://stackoverflow.com/questions/81406/parser-for-c-sharp – Dlinny_Lag Mar 24 '14 at 05:26
  • 7
    @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. – swasheck Mar 26 '14 at 16:37

2 Answers2

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.

Paul Sinnema
  • 2,534
  • 2
  • 20
  • 33
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.

Michał Komorowski
  • 6,198
  • 1
  • 20
  • 24
  • 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. – Paul Sinnema Mar 24 '14 at 08:31