Using a DSL to generate C# Code
Asked Answered
B

3

6

Currently the project I'm working with does not have completely fixed models (due to an external influence) and hence I'd like some flexibility in writing them. Currently they are replicated across three different layers of the application (db, web api and client) and each has similar logic in it (ie. validation).

I was wondering if there is an approach that would allow me to write a model file (say in ruby), and then have it convert that model into the necessary c# files. Currently it seems I'm just writing a lot of boilerplate code that may change at any stage, whereas this generated approach would allow me to focus on much more important things.

Does anyone have a recommendation for something like this, a dsl/language I can do this in, and does anyone have any experience regarding something like this?

Basketry answered 19/3, 2009 at 6:32 Comment(0)
D
5

This can be easily done with ANTLR. If the output is similar enough you can simply use the text templating mechanism—otherwise it can generate an abstract syntax tree for you to traverse.

Dc answered 20/3, 2009 at 22:4 Comment(0)
A
5

I have seen a system that used partial classes and partial methods to allow for regeneration of code without affecting custom code. The "rules engine" if you will was completely generated from a Visio state diagram. This is basically poor mans workflow but very easy to modify. The Viso diagram was exported to XML which was read in using powershell and T4 to generate the classes.

The above example is of an external DSL. I.E. external to the programming language that the application runs in. You could on the other hand create an internal DSL which is implemented and used in a programming language.

This and the previous article on DSLSs from Code-Magazine are quite good.

In the above link Neal Ford shows you how to create an internal DSL in C# using a fluent interface.

One thing he hasn't mentioned yet is that you can put this attribute [EditorBrowsable(EditorBrowsableState.Never)] on your methods so that they don't appear to intellisense. This means that you can hide the non-DSL (if you will) methods on the class from the user of the DSL making the fluent API much more discoverable.

You can see a fluent interface being written live in this video series by Daniel Cazzulino on writing an IoC container with TDD

On the subject of external DSLs you also have the option of Oslo (CTP at the moment) which is quite powerful in it's ability to let you create external DSLs that can be executed directly rather than for the use of code generation which come to think of it isn't really much of a DSL at all.

Abase answered 19/3, 2009 at 7:20 Comment(2)
A lot of full-blown compilers are really code generators. The original C++ compiler, cfront, generated straight C code, and Eiffel and Haskell also compile to C before going to binary.Dc
All compilers are code generators, they just might not generate human-friendly code. Even machine code instructions are typically just higher level instructions interpreted by microcode embedded within a processor.Everrs
D
5

This can be easily done with ANTLR. If the output is similar enough you can simply use the text templating mechanism—otherwise it can generate an abstract syntax tree for you to traverse.

Dc answered 20/3, 2009 at 22:4 Comment(0)
I
1

I think you are on the right track.

What I usually do in a situation like this is design a simple language that captures my needs and write a LL1 (Recursive Descent) parser for it.

If the language has to have non-trivial C# syntax in it, I can either quote that, or just wrap it in brackets that I can recognize, and just pass it through to the output code.

I can either have it generate a parse tree structure, and generate say 3 different kinds of code from that, or I can just have it generate code on the fly, either using a mode variable with 3 values, or just simultaneously write code to 3 different output files.

There's more than one way to do it. If you are afraid of writing parsers (as some programmers are), there is lots of help elsewhere on SO.

Impervious answered 20/3, 2009 at 21:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.