Before reading this post, please read the following posts:
Define an entry point into a Domain Specific Language that is responsible for building up the Semantic Model.
The implementation of this pattern is accomplished by providing a base class. Using the “language” is done by subclassing and calling statements from the constructor.
The base class is used to provide expressions that can be consumed by the subclasses. It’s also responsible for setting up the “defaults” so that only minimal use of the language is required.
Pattern in Action
Let’s take a look at an example base class (Registry):
There are a few things to note here:
This is the common method signature found in a Registry. For our example, we used: StringifierModel BuildModel(). The consuming component (typically some form of bootstrapping mechanism) uses this method to retrieve the semantic model.
The default constructor is used to call methods on itself to register default values. In our example, we’re registering our default stringifier.
This is where we start utilizing Fluent Interfaces to empower our language. Let’s look at the method signature: ConfigureStringifierExpression IfRequestMatches(Func<StringifyRequest, bool> predicate)
Do you remember our IStringifier interface from my previous post?
Let’s make a flexible implementation of this:
And we’ll look at the configure expression:
The idea is that IfRequestMatches is an ExpressionBuilder for configuring an instance of LambdaStringifier.
Just to wrap it up a little, let’s look at an example of a subclass of our registry:
You’ve seen the pattern with a primitive example. Let’s wrap it up by showing off an example of where we use it in FubuMVC.