Code Generation in ORM

Recently, I had a heated discussion in a .Net list about ORM tools that are centered around code-generation, like Subsonic. (Okay, okay, SubSonic is more than ORM). While SubSonic has a very decent ORM solution, I can’t agree that code-generator produces decent ORM.

First of all, code-generator *conveniently* produces all entity’s properties as public getters and setters. This conveniency is exactly what I refer to as violation of encapsulation notion in OO principles. When an entity exposes all of its states, it becomes very easy for layers above it to change them. And this easiness is not a good thing. It leads into the an unmanagable code where making a small change would involve poring over thousands of lines of code. By letting anyone to freely mutate entity’s states, we allow business logic to be just dumped into a class and be called.

Second problem is that all auto-generated classes are practically owned by the auto-generator. They steal them from you. Remember, if we somehow attempt to change the autogenerated code, we will lose it the next time we run auto-generation. We no longer own the classes. If we can’t add any behavior to the entities, then they will be nothing more than a mere dumb data cargo. Anemic Model, the same problem that I had before. It’s just CLR version of databse table. Then someone will need to give me a good reason why I still should call it Object Relational Mapping?

The argument about productivity advantage offered by code-generation is not entirely valid either. Now there are 2 parts of a typical business application (among others): domain objects and database. Subsonic autogenerates domain objects from database structure. The others (like NHibernate) generates database structure from domain objects. None can generate both, which is good news for us, software developers, since we apparently are still worth some salary.

The question left is now which one you want to write yourself, and which one you want the machine to do for you.

If you’re writing an business application that involves complex business logic, then you will find domain objects as the heart of your application. And you will want to write them yourself. The tedious part of managing persistence can then be delegated to our fool auto-migration. This is the most common approach in NHibernate.

Now if you’re working in data-centric application, particularly thus involving complex data structure, then you will find your database as the heart of your application. You spend most of your time on tables and SQL scripts. In this case, domain object is just a boring part that merely sits there to bridge your data to presentation. Let code-generator does the brainless job for you. And SubSonic is really good on this. Castle AR and NHibernate also provide this approach.

Having the codebase owned by the tool is not necessarily a bad thing. If we don’t own the code, then we don’t have to spend the cost of maintaining it. The tool owns the code, the tool nurtures it for you.

Another arguably good situation where you should use code-generation for ORM is when you’re working on legacy database, typically when you are rewriting legacy code. This is probably true, but I would only use the auto-generated entities as datastructures, not as objects. Pretty much to treat them as dataset, where you need to add an adapter layer to map them into domain objects that will be the only things used by the rest of the application.

Either way, most people wouldn’t classify code-generations (like Linq2Sql and Subsonic) as ORM, because, quite obvious, there is no mapping going on there. It’s just a strongly typed interface to database tables. To bridge impedance gap between the 2 worlds, you will have to write your own mapping from auto-generated *table-object* into your own domain entity.

Advertisements

Unity vs Anemic Domain Model

It’s so unfortunate that one of the most important features of a DI container that leads to good design can hardly be found on DI products (.Net) today. And the only major one that does support it, is ironically one that is widely considered most inferior in the competition: Microsoft Unity Application Block.

The feature I am talking about is post-instantiation configuration. Or BuildUp() method in Unity. That is, the ability to resolve dependencies of instantiated object. This is the only single feature that stands out as the most interesting aspect I can find from Unity. And by the way, the good design I am talking about, is avoiding Anemic Domain Model.

A class in object-orientation by definition should have both structure and behavior. EJB decided to srew this up by introducing seperation between Session Beans and Entity Beans. Entity beans were fetched from DB, containing only getters and setters, then passed around like cargo between services layers (Session Beans) where all business operations happened.

Dependency Injection came to rescue. Suddenly POJO was becoming the hottest buzzword of the days. Now instead of orderSubmissionService.Submit(order), people found new love to cleaner order.Submit(). Some people even take it further with fluent interface: order.Submit().From(thisStore).NotifyProgressTo(customerEmail).And(agentEmail);

So ideally, the domain object would contain behavior to deal with its own processing and persistence. If domain objects offer such behavior, the service layer will deal with them in object-oriented fashion. Thus, instead of telling OrderSubmissionService to submit an order, the application layer will tell the Order to submit itself.

This makes the code cleaner and easier to maintain. There might still be OrderSubmissionService though, sitting below the skin of Order.Submit(). And we expect DI container to make this OrderSubmissionService accessible for Order instance. Unfortunately, this is where DI containers and ORM today fall short.

Even after the the collapse of EJB era, and with Domain-Driven-Design gaining its fame, the way people architect entities has not changed that much. Today’s DI containers do not even make it easy for an entity to do their job.

Entities are typically instantiated by tools like Hibernate, and thus most DI containers do not support to resolve dependencies for these objects. Preventing our Order entity to do its job. People then end up switching back to the old way by placing business logic in DI-able service layers.

The fact is, this single feature is very easy to implement. My post shows that it won’t take more than few lines of code to make it happens. And I think the Microsoft PnP team has made a really good decision to bring this trivial but important feature.

(OT) Land of Sheeps

I’ve been out (or rather, back) to Auckland for several days now. The sun is bright, and the sheeps are healthy. But apparently, my Australia phone doesn’t work here. Don’t even bother trying my old NZ phone. The card has died miserably in rust, although technically it’s still active. I’m using a new number, but hey, God bless email technology. So if you’re to reach me, you know where to go.

I have no idea how long I’ll be here for, but we’re talking about weeks rather than months. If you’re now in Auckland, I’m up for a drink or two.

And oh, I also notice I’ve got significantly better in packing. I haven’t stayed in one place longer than 4 months during the past 2 years, where I’ve spent more mornings in front of suitcases than wardrobes; yet it had never taken me less than a day to get a packed suitcase from scratch. But this time, I did it in less than 3 hours!! Less defects too. Well done! Once you get the logic behind it, and use the correct patterns for the job, it’s apparently not that hard.

I know, I haven’t posted anything for a while, and the only thing I’m coming back with is just about sheeps and suitcase-development-lifecycle (SDLC). This is so wrong.