Something about
Ayende inspires me to build something. I got to thinking today about how I could create a DSL for NHibernate mapping files. What's wrong with XML, you say? Well...
- It's verbose - XML is known for it's ability to easily validate based on a schema, not for readability. In other words, XML was designed for computers, not humans. Since I am a human (are you?) I would prefer something a bit more friendly.
- Schema Validation takes time - Usually you don't notice, but some recent metrics show that it can account for more than 1/2 of the startup time for NHibernate when there are many mapping files. If you have an appliaction with 1000 entities, arguably you have bigger problems than XML's readability and schema validation performance, but it IS noticable so hey....
- Generates runtimes errors for semantic structure - Sure, the syntax is validated, but there are so many things that can go wrong with runtime compilation (that's a weird term) of mappings.
So I got to thinking how we could do better. Here's what I came up with (with some additions from Ayende) -- it's in Boo:
import flux88.NHibernate.Mapping
mapping Test.Project, Test.Project.Entities
entity Customer,
table: Customers
default_access: "nosetter.camelcase-underscore"entity Customer,
identity "Id",
generator: "native"
property Name,
column: "CustomerName",
type: "String(12)",
nullable: false
property DateJoined,
property Address,
type: "String(200)"
set _orders,
access: "field",
manyToMany Order,
table: Orders,
pk_column: "customer_id",
fk_column: "order_id",
inverse: true
entity Order,
table: Orders
Note that there isn't a ton of extra fluff, it's meant to be light-weight and easy to write. Additionally you could set defaults at the top (like default_access) so that you can avoid typing it all over your mappings.
Ayende added the notion of doing this:
for type in assembly.GetTypes():
continue if type.Namespace != "My.Model"
entity type.Name, type.Namespace:
idenity "id"
for prop in type.GetProperties():
property prop.Name
You get the idea.
There could be a number of benefits of doing it like this. First, you can compile it, so you can get syntax errors notified. If you use the BooExplorer I'm pretty sure you'd get intellisense for this. I could also see plugging this into a model validator that would reflect over the model and make sure that all of the properties and access strategies will work with the mapping as defined.
Anyway, I have some reading up on DSL's to do... Ayende, that means I need you to write that book on DSLs with Boo :) Can I have it next week?
Thoughts? Suggestions?