For the last two weeks I’ve been engaged in implementing an internal Domain Specific Language (DSL) for dealing with the ribbon in a Windows Forms composite client. For those of you who haven’t heard of the ribbon before, it’s the new user interface) microsoft introduced with MS Office 2007. Those two weeks have really been interesting, mostly because this was the first time I actually tried to build a large internal DSL.
In this post I would like to talk a bit about internal dsls, the implementation of the ribbon dsl and what I learned from those two weeks …
So, what is actually an internal dsl?
So what is an internal dsl actually? An internal dsl is basically just another style of an API, which follows a more language-oriented approach. Instead of following the classic CommandQuerySeparation - principle, it encourages a more fluent style of programming, which when read out loud by a reader is intent revealing enough to understand what the code basically does. Martin Fowler and Eric Evans coined the term fluent API to describe this behavior, which I will use too in the rest of this post. Source code and pictures usally say more than a hundred words, so here a some examples for fluent APIs.
1 2 3 4
1 2 3 4 5 6 7
Did you notice one thing the examples above all have in common? Yes, they’ re all OSS! A lot of OSS-projects have embraced fluent APIs in the past or seem to embrace this API style lately. Although they’re currently just the minority of existing APIs out there, it’s interesting to watch the emergence of more language-oriented APIs, even in the .NET Framework core. I think nobody will slap me when I say that Linq can be described as an internal dsl for querying data. You may have guessed it, I like fluent APIs a lot. I won’t say they are applicable everywhere, but personally I think there are places where they can give you quite a bit advantage in readability and testability over regular APIs. Especially configuration and specification scenarios are very well suited for fluent apis.
Possible ingredients of a fluent API
The basic idea of method-chaining is that you directly use the return value of a method in order to invoke a method on it and repeat this as long as needed in order to make sense as a complete sentence. The easiest way to achieve this is a class whose methods all return a this reference. Here’s a simplified example of something I’ve written earlier this year. It’s a kind of specification that describes the details of a form which a form framework should create. Don’t worry about the details. This is just a shortened example.
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6
One personal note to method chaining: If you’re using a mock framework like for instance
Rhino.Mocks better don’t try to mock out a fluent interface.
Find other ways to test it. So, why am I saying this? Most mocking framework don’t have a natural syntax for configuring the expectations on fluent apis (except
TypeMock). Because of that you have to
configure every call on the chain step by step, which is a) very tedious and b) also results in not well readable tests (which mostly smell, too).
The form example above is what I mostly do in order to get better testability. I mostly use fluent APIs as builders, which produce something I can easily test / verify
(In the example above it’s the configured
FormExpression). Most of the fluent API’s I created used the
Fluent Builder pattern.
The basic pattern for
Fluent Builder can be easily described: Method chaining + an implicit conversion operator for the convertion into the build product.
1 2 3 4
When I was implementing the ribbon fluent API however, I used a variation of a different pattern which is called
Expression Builder. The idea of the
pattern is that the fluent API only is layer on top of a regular API. It serves as a kind of facade to the other api. This was especially useful because I didn’t want the ribbon API to be coupled to a particular
vendor implementation. Instead the API uses interfaces and a facade in order to perform actions on the concrete ribbon control. Please have a bit patience, I’ll show code soon.
Read here for a bit more on
One problem with fluent APIs implemented only with method chaining is extensibility or reusability.Â A short example. Let’s assume we have a typical OO
situation with two products having a lot of properties in common but also some special ones. Let us further assume that we want to build
fluent builders for each of them. One approach is to use a
Fluent Builder base class and derived builders for each product. When you do
this you have an API in which some of the methods (those implemented by the builder base class) return only a subset of the API (because they
only return an instance of the base class). In order to use the methods of the derived
Fluent Builder in combination with those of the base
class you have to call the special methods first before continuing with the base class method in the fluent chain.
You can get around this (look here) for more informations) with redefinition and the new operator, but imho
it doesn’t smell very good. However I haven’t found a solution which solves the problem and makes me happy. Has anyone found a better
solution? I would like to hear other thoughts on this. With that beeing said, how can extensibility be tackled without sacrificing the language
orientation. That’s where
Nested Functions come into play. The basic idea is that you compose your fluent API out of several independant
parts/ functions. A good example for this is the constraint API that
NUnit provides. Look at the signature of the
That method of the
1 2 3 4 5 6 7
Doesn’t really look fluent first, doesn’t it? But combined with a static entrypoint and a derived constraint
NUnit is able to achive a very nice and well
readable syntax for specifiing tests.
For me this API is just a single piece of beauty. Awesome :-).
You can read more about
Nested Functions here.
That’s all I’ d wanted to show you about fluent APIs in this post. If you’re interested in learning more about fluent APIs I would highly recommend Martin Fowlers current articles about DSLs. Although they’re work in progress (as part of an upcoming book), I consider them best resource for learning about dsls available at the moment. Before I’ll show bit from the ribbon API I want to give you an impression what the actual requirements for the API were.
The basic requirements for the ribbon API
- The API should provide benefit in a composite (windows forms) architecture, where modules are loosly coupled and UI configuration is scattered through several modules. From a product level perspective the API should enable very exact (and relative) positioning of elements while the load order of modules might change.
- The interaction with the ribbon should be testable with unit tests.
- Consumer code of the API should not be coupled to a particular vendor implementation of the ribbon.
- Consumer code should be able to configure the ribbon from any thread.
- Configuration via an external XML - file should be possible (although not implemented in the current version).
An internal dsl for the ribbon
One of my earliest design decisions was to design the ribbon API to be based on the
internally. The decoupling that was possible with such a design allows a good level of control over the execution of the commands (which is
very important while initializing modules (Requirement 1) ). Besides that commands are a good candidate for testability, because the
configuration of the commands can be tested via unit tests whithout actually having to execute them. Because of that I decided to implement
a little variation of the
Fluent / Expression Builder topic. Let’s look at some code. There are four static entrypoints for creating fluent
These are the
CreateNew class, which creates commands that when executed configure the ribbon UI,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Enable and the
Disable class for creating commands, which enable
or disable elements on the ribbon,
ChangeVisibilityOf class for creating commands, which change the visibillity of elements on the ribbon,
Access class for creating commands, which perform other read or write
operations on elements on the ribbon.
The commands execute against a internal facade for the ribbon. This facade is completely based on
interfaces and can be adapted to different vendor APIs (at least thats the idea :-)). This is the regular API to which I referred when I
Expression Builder previously. The next code sample shows the implementation of the
NewTabCommand for creating new tabs on the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Commands are executed with the
ICommandExecutor. Main responsibility of the service is to allow thread safe access to the ribbon (which runs in the UI thread), so that the
module initialization can run multi-threaded. Is has several overloads for running commands. This is one of them:
1 2 3 4 5 6 7 8 9
To complete the picture I wrote custom assertion to make testing easy.
1 2 3 4 5 6
Some final thoughts to conclude this post
It’s harder than I orignally thought to create large fluent APIs in C#. Especially code reuse and extensibility can be barriers. C# as a statically typed language is somehow limited here (One more reason to learn more about Ruby and Boo …). I’m particulary don’t like reusability through builder inheritance and method redefinition, though I’m doing it because of a lack of options. Again, does anyone know a way in C# around this? Finally I really like the readability and testability of what I’ve implemented, although there is still a lot room for improvements. Feel free to post (positive and negative) thoughts on this or domain specific languages in general. Read you soon :-)