The idea for this post came by a very good friend who wanted to modify his data access layer (DAL) in order to use NHibernate.
The DAL contains a base class that generates SQL queries and the application were it's used is completely data-driven. There is no domain, no classes, and the behaviour is bound in various event handler methods. Changes to the database (columns, row data, etc) dictate how the application behaves.
The problem that comes when trying to port this kind of DAL to use NHibernate is that we have to create POCOs in order to persist everything to the database. Since the application is data-driven we would end up using an anemic domain model holding just the data to persist to the database and no behaviour at all.
The solution for the problem is to use dictionaries as entities, a little-known feature of NHibernate which allows us to define our entities as dictionaries instead of statically typed objects.
Here is how to define a mapping, (notice the entity-name instead of a class name):
The only thing we have is the mapping, no classes. In order to create a Currency object we create the following dictionary:
As you can see, the above code is cumbersome. But we can do something about it.
Taking advantage of the .NET 4.0 and the DynamicObject Class, we can create a type deriving from the DynamicObject Class and specify dynamic behaviour at run time.
Let's name our class, DynamicEntity. It must be able to:
- Accept a String in the .ctor specifying the entity name.
- Set properties (PropertyName = key, PropertyValue = value) on the internal dictionary.
- Get properties (similar to above) from the internal dictionary.
- Being able to expose the internal dictionary as property for NHibernate usage.
- Being able to expose it's name as property for NHibernate usage.
Here is the DynamicEntity class:
Finally, here is an integration test in action:
In the above test, for Session I use the ISession.GetSession(EntityMode.Map).