Designing layered app with NHibernate and context changing database
I'm designing a C# application
- Presentation ( web site + flex apps )
- Business Logical Layer (might be WCF to enable multi client platforms)
- Data Access Layer ( With NHibernate )
We're going to integrate our solution in many preexistant client's database environnements and we would like to use NHibernate in the DAL.. My colleague pointed out that generating classes from client's DB (like User or Image) with NHibernate would cause the BLL to blow up in our face at each DB changes ! So the question is how do we prevent that from happening ? We're thinking about creating business objects and map NHibernate objects to these BO (hum, does that make them DTOs ?) with AutoMapper and prevent dal changes from affecting BLL.. Is this the way to go ?
To give a better understanding of what we're trying to achieve, you might need context : We're building a photo storing/sharing app in Flex for the front-end and C# on the back-end mainly for our company, so we handle every aspects of the code and DB.
But : that product can also be bought by tiers, which eventually have already a database with User table or Image table. I'm thinking here about a new prospect who have an Image table with a few hundred millions of rows and adding columns for our business logic isn't going to be happening because of a too long ALTERing of the table.
Even though it would be possible (User table for example can be modified because of lesser rows), we're asking ourselves how to handle table structure changes without impacting all of our solution each time we have to integrate in a tier database, from BLL to client app in Flex !
in my experience, your business objects (AKA Domain Objects) should be modelled in OO to represent your real life business entities and your tables in 3rd normal form (this may change depending on what design you are after speed vs file size)
NHibernate should map between your BO's and Tables, using its mapping files.
now you have legitimate cases:
- You need to add/remove a column, we decided to remove addressline4, this will echo a change in your Address Object, thats fine.
- You move a column to a better place, our Client object contains notes, which is currently stored in the Contract_Extra table, which is going to be moved into the Client table. moving the column into a better place will only effect the Mapping file, in this case
I doubt there is a blanket reasoning, however I hope the examples make you think about this
I have not tried NH accross multiple Db's, also should each database have its own service on top?
here are some links
- Multi table entites
- PoEAA <- look at the Single Table inheritance, Class table inheritance and the other one
Hope this helps
It sounds like you want to design your domain model to be database agnostic. I too am interested in the best approach to having a central domain model that can map over to multiple different database models.
The way you are proposing, to create DTO's from each database using code generators, could be an option. Another would be to create custom NHibernate mappings for each preexisting database. You still may need to use some DTOs to make some of the mappings less difficult but it may give you more control.
These are just some thoughts. More experienced users with NHibernate probably will have better insight to your situation.