Patterns of Compositional Architecture: DSLs – Conventions
This is the fourth post in the Patterns of Compositional Architecture series that I mentioned in my introductory post.
Prerequisites
Before reading this post, please read the following posts:
The Pattern
Provide an ability to modify the underlying semantic model.
Overview
The implementation of this pattern is actually quite simple if you have a true semantic model. The interface looks something like this:
Pattern in Action
Our sample is simplistic so we don’t have a lot going on during the build up of our model. The most common applications of DSL patterns will have the Build method create a new instance of the model and then systematically apply conventions.
Since the creation and initialization is often order-sensitive, conventions are used to allow users of your DSL to apply changes to the model after it has been created and initialized with baseline data.
Let’s revisit our Stringifier example and modify the StringifierRegistry to leverage conventions:
During the construction of the model (although trivial in this example), we run through and execute each convention. Now, just for sake of examples, let’s write a sample convention:
I should note that one of the benefits of conventions is the modularity of your opinions. They can be broken out into reusable pieces that get applied to your projects and help structure your work.
Real-World Example
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.
The Convention
IConfigurationAction. This is the interface used by the FubuRegistry to register conventions that operate on FubuMVC’s semantic model: the BehaviorGraph.
The Registry
FubuRegistry.BuildGraph(). This method makes use of a simple extension method on IList
Almost all of the core configuration of the behavior graph is done through internal conventions. Since order matters, there are multiple collections of conventions that are exposed through the language (conventions and policies), and others used for internal use (explicits and system policies).