.NET: Minimizing the cost of change

ShotgunOn of the things that I always liked about Ruby on Rails was the low cost of making a change to the data model. Because rails has migrations and because the object-relational mapping is accomplished at runtime using reflection, a new property can be added to a class by simply changing the migration.

In a standard application that uses object-relational mapping making a change to the data model requires three changes: changing the database schema, changing the mapping metadata and changing the domain model. This is bad because:

• having the same information in three places is a violation of the Don't Repeat Yourself (DRY) principle.
• a single change to the application requires three code changes. This is an example of the Shotgun Surgery antipattern.

Fortunately, there is a solution for the .NET developer. Auto Mapping is a part of Fluent NHibernate. It uses conventions and reflection to map a domain model to a database. Combined with NHibernate's schema generation this brings the amount of code changes required to add a new property down to one. When a property is added to a class it is automatically mapped by Fluent NHibernate's Auto Mapper, which means that it is automatically added to the generated database schema.

One of my reservations about NHibernate is that is exposes to many options - making it hard to get started and hard to learn. Automapping has almost the opposite problem. To be efficient your domain model must be reasonably close to the expected conventions. It is possible, but not trivial, to change the conventions.

In my application I changed the convention for mapping one-to-many relationships so that saves, updates and deletes are automatically cascaded. This is done by implementing IHasManyConvention. There are similar interfaces to implement to change the other conventions. Here is my code:

    public class OneToManyConvention : IHasManyConvention
    {
        public bool Accept(IOneToManyPart target)
        {
            return true;
        }

        public void Apply(IOneToManyPart target)
        {
            target.Cascade.All();
        }
    }

I like Auto Mapping because I like convention over configuration. Even if I have to make some compromises on the mappings it is still worth it for the time that is saved creating and maintaining mappings. Auto mapping can be combined with regular fluent nhibernate for situations where more control is needed. Thank you to the fluent nhibernate team for this excellent library.


Comments

Comments are closed