Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we construct an assembly from both CodeExpressions and literal source code at the same time?

I have a situation where one part of my code is generated through CodeExpressions and the other by the user himself (as in: the user simply writes his code as usual, which I would then take and add to my assembly when he compiles).

Is it possible to generate an assembly that contains both of these items? Caveat: these two approaches will contain partial classes so they have to be in the same assembly.

Another approach I had in mind was by perhaps translating both of these to a string representation and then generating the assembly from that string, but I doubt I can get the source code from a type generated by the user (at compile-time).

Working on that idea I could write the CodeExpressions generated code to a textfile and combine that with the .cs files. A timeline would look like this:

  • User wrote his classes
  • CodeDom tree is setup programmatically
  • User builds the project
  • CodeDom generates source to a textfile
  • Program reads contents of the user-defined .cs files
  • Program reads generated textfile
  • Program combines these two
  • Program creates a new .dll from the combined source code

I could skip the (redundant) steps of writing and reading of my generated CodeDom source to a textfile and simply write it to memory as well, ofcourse. In fact, it might just be easiest to use Pre-Processed T4 templates and load the results of these templates into memory and compile an assembly from that string.

As you can see, this is very messy but right now it looks the most feasible one. Have I looked over any options that might make this easier?

Background:

I'm creating a library that will create an assembly with classes that are defined by the user. The way this works is in the following order:

  • User references my library in his project
  • User creates new TinyTypeSetup instance
  • User adds Tiny Type definitions to it
  • User runs program
  • Program generates assembly from the given types through CodeDom

What I am trying to add now is the possibility for the user to create his own source files and add those files immediately to the assembly that gets generated. This would allow the user to specify partial classes with his own methods, on top of those I generate myself.

like image 746
Jeroen Vannevel Avatar asked Apr 05 '14 20:04

Jeroen Vannevel


1 Answers

You are not talking about a scenario where CodeExpression is ever useful. It is a source code generator, the specific kind of source code that gets generated is determined by the provider you selected.

But at no point does the user of your project actually care about that language in your envisioned usage. He never looks at it, he never compiles it himself. Only you care, you have to pick the right CodeCompiler. The user only picks the assembly it produces. And by .NET conventions, the language that was used to create an assembly never matters. The metadata inside the assembly is entirely language-agnostic.

CodeObjects are useful in a scenario where source code is automatically generated and added to the user's project. To be compiled, later, when the user builds his project. Good examples are the various designers built into Visual Studio, like the Resource designer and the Winforms designer. By necessity, they must generate code that matches the user's project type.

It should strongly be avoided if you don't need it. Biggest hangup with the CodeDom code generators is that it is only capable of generating a subset of the statements that are valid in a language. And of course ugly to use, it litters your code. You only need to generate text, the language you pick doesn't matter. Since you seem to favor C#, that's the kind of text you ought to generate.

Do consider the bigger solution. It probably would work a lot better if the user can in fact open a custom designer inside Visual Studio itself. So this extra step, running that translator to go from TinyType to an assembly isn't needed anymore. Easier to use, lights-up IntelliSense as well. Now it does make sense to generate code. This is going to take a lot of work, creating designers isn't that simple. Do keep your eyes on the ball, no user is going to enjoy generating that XML file you need. Creating tiny types in C# is already easy, it just doesn't need much help. Either way, the user composing his own types from your tiny types just doesn't need any help either. VS already supports it directly.

like image 125
Hans Passant Avatar answered Nov 20 '22 12:11

Hans Passant