The "facets-enabled" meta model

During the course of my current project at work, I've been trying to come up with a way to describe the meta data of my domain model (which I dubbed the meta model).  Because I've taking a rather ObjectSpaces-like approach to object-relational mapping, the domain schema I created seemed like a good place to store the facets of my class members(fields and/or properties). Here's an example of what it looks like:
<?xml version="1.0" encoding="UTF-8"?>
<
DomainSchema AssemblyFullName="SomeProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
xmlns="http://www.seagile.com/domainschema-1.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.seagile.com/domainschema-1.0/
D:\WorkSpace\SomeProject\trunk\Schemas\DomainSchema.xsd"
>
    <Classes>
        <Class FullName="Seagile.SomeProject.SomeBaseClass" IdentityMember="ID">
            <Members>
                <Member Name="ID" Field="_id" Type="System.Guid"/>
            </Members>
        </Class>
        <Class FullName="Seagile.SomeProject.SomeClass" BaseClass="Seagile.SomeProject.SomeBaseClass">
            <Members>
                <Member Name="Name" Field="_name" Type="System.String">
                    <Facets>
                        <MinLength>1</MinLength>
                        <MaxLength>5</MaxLength>
                    </Facets>
                </Member>
                <Member Name="ExternalCode" Property="ExternalCode" Type="System.String"
                    Required="False" Default="MCQ000">
                    <Facets>
                        <FixedLength>6</FixedLength>
                        <Pattern>^MCQ\d{3}$</Pattern>
                    </Facets>
                </Member>
                <RelationshipMember Name="Category" Field="_category" RelationshipType="One"
                    TargetClass="Seagile.SomeProject.SomeOtherClass"/>
                <RelationshipMember Name="Materials" Field="_materials" RelationshipType="Many"
                    TargetClass="Seagile.SomeProject.Material"/>
            </Members>
        </Class>
        <Class FullName="Seagile.SomeProject.Material" BaseClass="Seagile.SomeProject.SomeBaseClass">
            <Members>
                <Member Name="Name" Field="_name" Type="System.String"/>
                <Member Name="TotalParts" Field="_totalParts" Type="System.Int32">
                    <Facets>
                        <MinInclusive>2</MinInclusive>
                        <MaxExclusive>11</MaxExclusive>
                    </Facets>
                </Member>
                <Member Name="BarCode" Field="_barCode" Type="Seagile.SomeOtherProject.BarCode, SomeOtherProject"
                    TypeConverter="Seagile.SomeOtherProject.Data.BarCodeConverter, SomeOtherProject.Data"/>
            </Members>
        </Class>
    </Classes>
</DomainSchema>
By itself the schema is worth nothing, but in conjunction with a mapping and relational schema it's "easy" for a generic mapping layer to interpret how to retrieve and store objects. Strictly speaking the mapping layer doesn't need the type information and facets. But their presence is very much appreciated by the domain, application and presentation layers. The presentation layer can use the information to constrain the input fields, and both the domain and application layer can feed these facet values to validators (LengthValidator, RegularExpressionValidator, Int32RangeValidator, ...).
The xml representation is both a blessing and a curse. On one side, it's very easy to get up and running (using an xml schema to drive the intellisense and validation). It feels like a modelling tool if the schema is what you start out with. If the domain model is already in place it's a pesky task. Maintenance wise, however, it's a little devil. Having a validator to compare the declarative xml representation against an assembly is not a luxury. Keeping the code and xml in sync is asking for trouble. I think the best way to handle this is (a) to forget this whole idea, (b) have the xml representation generate the code or (c) have the code generate (attribute-based approach) the xml representation.
But lets not forget the problem I'm trying to solve, namely preventing the scattering of the domain's meta data. Where do you store the fact a column is 5 long, how do you constrain the textbox representing that same conceptual value to only take 5 characters to have an overal nice end-user experience, and how about duplicating that value once more in the domain layer so that other "clients" of your code play by the rules? How do you deal with change and know where to look if 5 becomes 10?
Published 08 April 2005 08:04 PM by yreynhout

Comments

# matt said on 08 April, 2005 03:03 PM
During my O/R dreams...which are occuring nightly lately, I've thought about creating a similiar XML schema to capture the model's meta data.

I'm especially interested in the relationships between the domain items. Such as, one-to-many, or a reference to a type/status code using the (PK), etc...

If there was a way to capture the relatiohsips already contained in the data model...and to export and transform this "meta" data to an XML --> this would be great. I would use the XML meta-schema to code generate my classes, etc...

Leave a Comment

(required) 
(required) 
(optional)
(required)