It has been a journey so I’ll try to emphasis only the important stopovers and turnovers I passed by.
Back in 2005, I was still new to .NET but with good professional & unprofessional experience with many different other languages. I started like everyone and I say like everyone because I found that there's a path that unintentionally many follow it step by step. May be some was faster than others & some stopped & didn’t continue. This path represented a natural evolving path of ideas & techniques for me & many others.
I started from reading about Data Access Layers & how to build a DAL in a layered application architecture.
So, I started to search for a better way to do it. I built my first, and last, DAL framework and called it "EntityDAC".
It was based on an abstract base class I called EntityDAC that every DAC object, or DAO, inherits from in order to do basic CRUD operations on a certain table. I used this in a project then I found things getting more complex. The major shortcoming was due to inflexibility in querying. So, I started to look around for a better solution. Here, I read a remarkable statement that meant for me that I shouldn’t re-invent the wheel, there are others who already wrote Data Access frameworks & probably did it better & mature now. But, I think taking chance to write first trial by myself was important later to enable me to choose between different frameworks.
I found some tools that can generate classes from database directly. It was a great discovery at this time better than code generator that generate stored procedures & helper classes to call these procedures. But later I started to face troubles of re-generating those classes when I change my database. Then, I read about Persistence & the use of Persistence Layer instead of Data Access Layer. That was brilliant, Persistence layer was the most attractive concept I read at that time and still correct & valid till the date. It's a shift from what we used to called Data-Driven applications to real Object-Oriented applications. Persistence, from my humble point of view, It’s a thin layer that enables my domain entities & services to persist their state to database when needed. Why this is brilliant? We need to look from the right angle. First, my application mainly consists of Objects that represents Entities in problem domain. Interaction between these objects represents the application functionality. Storing results of these interactions is an optional issue not the major issue. In other words, not every application is Data-Driven application, but every Data-Driven application is an application (has functionalities, responsibilities & calculations). For example, Let’s say my client needs an Online Shopping application that sends the Site Admin or Shipping Officer an email when a new Customer submits a new Order, although that is stupid, that means there is no database here & application still valid & carry out its responsibilities. But If he decided to save these orders to database so he can query this information later that will require to persist the state of Customer & Order to some storage; like a database. Imagine having a thin layer that can simply perform the following.
1: newCustomer.Save();
2: newOrder.Save();
3: CommitChanges(); // this is a pseudo code
That is impressive. So now you can concentrate on the real business; What are the responsibilities of these entities; Customer and Order? and what is the expected interaction between them. Persistence also is not about just database we can extend this idea to other storages, like text files, xml files or whatever is proper as a storage.
Right, you can say that all or most of applications we write uses Relational Databases in the back-end but that should not make us think that all our job is to store some values in some rows & columns.
Even before this shift in my vision, I used to analyze problem domain carefully & try to reflect it into Objects that has proper names & responsibilities. But, at the beginning, I used to create the Data Model first then Object Model; while both models used to be very close in concept since that the origin is the same (my thoughts) :)
In the beginning of 2007, after I checked many tools & I started to distingue the ORM tools & after quick test-drives for many of them, I found NHibernate to be a great tool. Right, It’s tough to start and has a slightly high learning curve but a very decent tool. I built a simple application using It & in July 2007, I went into vacation in Egypt with my laptop & the new application. I had a plan to enjoy working on that application during vacation. First day, I opened my laptop to work on the application I found a message that MS SQL Server Evaluation expired. It was a shock, I forgot that I have installed MS SQL 2005 – 180 days evaluation on laptop. That means that I won’t work till I reach my office again. Then, I remembered that NHibernate is able to talk to many database engines & also it can generate schemas, but I didn’t try this before. I had MySQL on my laptop so I worked on writing a test to create the schema on MySQL, yes I used test as a tool :)
I failed first day after many many hours of work but succeeded in the next day after an hour. This application had a small suite of Unit Tests that I was reading about & trying to practice also. So, I ran tests & the surprise that everything was OK. Sure, today I understand that unit tests must not hit a database :D Let’s say those integration tests proved that NHibernate is a great tool & I can move from a Database System to another in NO TIME.
Also, I learned that unit testing is a great tool enables you to make changes with confidence ;)
Over time, I started to change my mindset, to start thinking of Objects first & don’t think about database that early.
Later, I started to read about Domain-Drive Design I found it very close to my approach from my humble point of view. But It contains a great refinement for these concepts that I hope to master it one day soon.
I found that ORM & Domain-Driven Design are best friends. Both think in Objects.
My happiness complete after I tried Fluent NHibernate for the first time when it was a beta project. It was the missing part to make NHibernate a complete great tool. Then Linq2NH was a good complementary to that stack.
The last team player was AutoMapper that enabled me to simply return DTOs from my service layer to UI layer.
I can’t claim mastering all these technologies or techniques but I’m highly interested in them & doing my best to master them, beside others sure.
I’d like to coin some statements that I consider them keys for dealing with ORM.
1. ORM starts with O, for Objects.
2. ORM is not about to mirror database objects into programming objects, but may be the opposite.
3. ORM is not just a tool to save records in database, although It does that awesomely.
4. ORM doesn’t hurt performance & by means of caching you can build a rocket-speed application :)
I hope that was useful & wasn't too long.
Although, we can make it really useful, I like to hear from guys interested in ORM topic.