Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a DSL to generate C# Code

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?

like image 436
laurencer Avatar asked Mar 19 '09 06:03

laurencer


3 Answers

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.

like image 137
Mark Cidade Avatar answered Sep 20 '22 00:09

Mark Cidade


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.

like image 36
Jonathan Parker Avatar answered Sep 21 '22 00:09

Jonathan Parker


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.

like image 24
Mike Dunlavey Avatar answered Sep 21 '22 00:09

Mike Dunlavey