DSL (Domain Specific Languages) - languages that are specific for solving problems in a particular domain (as opposed to general purpose languages such as Java or C #). There is a more detailed description and examples on
Wikipedia , but I want to write about how it is quite easy to embed your own DSL based on the
Boo language into the application (C #).
We were faced with a task - a service for online synchronization of data from Active Directory to the XXX corporate information system (users, organizational units, groups, etc.). The main obvious difficulty here is that each particular enterprise may have its own AD scheme (OrganizationalUnit may use OrganizationsUnit somewhere, groups, etc.), as well as their own classes for representing departments and employees in XXX system (its properties and logic, and we don’t know anything about them at the synchronization service level, only their base classes), and even different rules for synchronization (somewhere you need to synchronize posts, somewhere you don’t).
The solution seems to be offhand with specifying AD mapping in XXX via XML, such as this:

But a lot of problems come up here - the need to implement your own rule parser (which creates rules objects for XML) and the rules interpreter (which it performs), the limited capabilities of XML (for example, specify type conversion or a slightly more complicated calculation, for example, add login prefix with domain name, etc. The main advantage of XML is that it is easy to fasten the GUI to such rules, and the task is familiar and not solved once.
')
These problems have pushed us to the idea that the task fits the type of tasks that are well solved with the help of DSL. Since we didn’t have much experience and knowledge in this area, at first we did a little research and made a couple of prototypes. We were based mainly on
DSLs in Boo - Domain-Specific Languages in .NET and the
Rhino DSL framework from the author of the book.
Here are some DSL examples from the book:
DSL for setting authorization rules:

DSL to specify modular software delivery rules and module requirements (+ here is an example of the implementation of the DSL editor with Intellisense and syntax highlighting based on the code editor from SharpDevelop):

All these are examples of “internal” DSLs that are hosted in the Boo language, that is, the code above is a legal code for Boo that can be compiled into ordinary clr classes or interpreted. Boo is chosen because it has a fairly convenient syntax for DSL, rich possibilities for expanding the syntax (you can write macros, such as macros in C, but they manipulate not the text, but the syntax tree) + it is open and has a convenient compiler API in which You can easily embed your actions.
Especially convenient is the fact that Boo gives us the output of the usual .Net classes. As a result, after processing the files with DSL from Example 1, we get the Rule type, which has a method, for example, Evaluate (user), when called, the code on Boo will be executed, which will produce the result whether the user needs to be authorized. That is, from the point of view of the developer and the application, everything looks absolutely transparent, as if the rules, which are written in DSL, are written simply as ordinary code. Very cool.
Our result
Here is an example of a rather complicated rule that synchronizes users and OrganizationalUnit from AD to departments and employees of the XXX corporate system, while also taking into account the hierarchy of departments:

By the way, these rules are transparently debugged in the studio without installing any plug-ins into it.
Internal implementation
Actually, in fact, everything is simple and everything is done using standard Boo syntax. The rule is compiled in the context of our class, in which there are methods with the names rule, for_type, etc. So the code
for_type
userit is actually just a call to the for_type method with one string user parameter. And inside the method, we simply write the passed value to the property of the rule and then we can manipulate it.
Entity and ldap are rule properties with types that implement a special interface Boo - IQuackFoo, which allows you to implement dynamic typing in them (such as IExpandoObject and dynamic in C #). Therefore, when ldap.GivenName is written in a rule, the ldap class actually looks up the attribute named GivenName in the user's attributes and returns its value. Similarly with entity.
The only syntactically tricky place is the expression on entity.Sid == ldap.objectGUID. Here on is a meta-method that works at compile time and replaces the syntax tree of the entity.Sid == ldap.objectGUID expression with another. Specifically, here we simply parse the names of the properties by which the key is set from the tree and remember them. Meta-method looks like a simple method in C #, which is marked with a special attribute and which accepts a syntax tree as input and returns a new tree. It's simple :).
For details on the implementation, ask, or should you just read DSLs in Boo and pick Rhino DSL, everything is very well described there, and Rhino DSL allows you to connect to the DSL project on Boo in a couple of minutes.