Lately, a
lot of people where asking on mailing lists and users groups, how to
dynamically load and execute C# code. This code maybe be stored as expressions
in the database or will be entered by the user in some sort editor or whatever
they want to use, but the important thing is that the app should compile and
execute the code at runtime. Unlike Ruby or Python, C# does not support this
kind of stuff right out of the box. Fortunately, the Redmond guys had
implemented a nice library called Roslyn, which allows us to do this and a lot
of other crazy stuff.
Whereas
this was possible in the past by using reflection or the CodeDomProvider, it
were a lot of work (complex and error prone work), so, very few people did it.
In this
post I’m going to show a little app that uses Roslyn to compile and execute C#
code at runtime.
Instead of
work with expressions like 2+2 or a>b (a.k.a. the classic “hello world!”
example), I’ll work with something more close to a DSL. This DSL will evaluate
expressions against business objects and it'll move values back and forth. The
idea is provide a more real world example, not just a lab test.
Now suppose
we are working on a shopping cart DSL that allows sales people enter business rules
to modify the order processing pipeline. In order to keep things consistent, it
would make sense to use the same domain objects that the company’s ERP uses. As
it turns out, that is a really easy thing to do with Roslyn.
Something
that worth to mention is with Roslyn we must provide valid C# or VB code.
Unlike the Boo compiler, Roslyn does not allow us to extend the
language syntax (and this is by design). Obviously this is no good enough for
sales people, who ain't gonna learn C# in order to work with our DSL, but it’s
a great starting point for us, because with a little bit of source to
source translation we can get the job done (We don’t have to worry about
semantic analysis, operator’s precedence, etc., etc… all the heavy lifting will
done by the Roslyn compiler).
You can get the source code from github using this link
By reading
the unit tests you will understand how it works, there are just eleven of them,
so is not a big deal. In future post I’ll cover in more detail some aspects of
the Roslyn API internals, but I think this example will give you an easy to
read overview, on how to build a DSL on top of the Roslyn APIs.
In the next
post I'll be revising some design considerations that you may want to have in mind
while designing your DSL syntax as well as the business rule editor.
Comments
Post a Comment