views:

351

answers:

4

I'm thinking of writing a domain specific language (DSL) to model business objects. The DSL will not be executed, instead it will be used by a template based code generator (probably CodeSmith) to generate the .NET & SQL.

The DSL will need to support the definition of the following elements:

  • Classes (name & description)
  • Properties (name, friendly name, type, null/not null)
  • Simple validation (required, regex, range, etc..)
  • Relationships between classes (1 to 1, 1 to many, many to many)
  • Inheritance (ok, maybe in version 2)

Here's a simple example of what the DSL code might look like:

Class: Insured
  Desc: "Represents a person covered by an insurance policy"
  Prop: FirstName, "First Name", String(20), not null
  Prop: LastName, "Last Name", String(20), not null
  Prop: MailAddress, "Mailing Address", Address, not null
  Prop: SSN, "Social Security Number", String(9), null      
  Rule: RegEx, SSN, ^\d{9}$

Class: Address
  Prop: Line1, "Line 1", String(30), not null
  Prop: City, "City", String(30), not null
  Prop: State, "State", String(2), not null
  ...

For the sake of keeping the DSL simple the more complex validation rules will be coded in the target language. The current plan is to make the generated code off limits and add the more complex rules to subclasses.

Has anyone written something similar to this? Can you provide any tips or links to similar solutions?

+1  A: 

Suggest you take a look at OSLO, if only to avoid reinventing it.

Richard
Thanks for the link. At first glance it seems way more complex than what I'm looking for, but I'll keep reading about it.
Seth Reno
+2  A: 

It's fairly easy to automatically convert the structure you present into XML. From there, I imagine it's possible to write some sort of transformation via XSLT or XQuery into whatever end result you desire. I wrote a Visual Studio add-in called CodeGenUtils to facilitate doing the transformations.

If you really feel like writing your own parser, I would suggest looking at existing textual DSL solutions such as, e.g., JetBrains MPS.

Dmitri Nesteruk
Actually, MPS is not text-based.But it's still the best system for DSL programming I've ever seen.
Alexander Kosenkov
+1  A: 

I have a project called bdUnit where I used parts of the Oslo framework in creating a DSL that models user stories as C# interfaces and unit tests.

A portion of an example input:

begin story "AUserStory":
begin setup 
    @Person to have a ~Spouse(@Person) 
            ~IsActive(true) 
            ~Age(0) 
            ~IsDead(false) 
            and several ~Children(@Person)
            and a ~Location(@Location)
        I want a @Person to be able to #Kill another @Person
        I want a @Person to be able to #Marry another @Person
        I want to be able to #Find all @Person
    @Location to have a ~Latitude(0.0)
            and a ~Longitude(0.0)
end setup

The corresponding generated C# code:

[PluginFamily("bdUnit")]
public interface IPerson
{
 IPerson Spouse { get; set; }
 bool IsActive { get; set; }
 int Age { get; set; }
 bool IsDead { get; set; }
 IList<IPerson> Children { get; set; }
 ILocation Location { get; set; }
 void Kill(IPerson user);
 void Marry(IPerson user);
 void Find();
}

[PluginFamily("bdUnit")]
public interface ILocation
{
 decimal Latitude { get; set; }
 decimal Longitude { get; set; }
}

I compile the interfaces and tests in a dll so they are 'off-limits'. These interfaces can only be implemented in inheriting classes. I then use StructureMap to inject the required dependencies into the unit tests.

lynchjames
A: 

Hmm, it is from the Java world, however using Eclipse project TMF Xtext such a task will be done in minutes. Check out their homepage, thei provide very similar example.

Gabriel Ščerbák