A couple of monthgs ago Ayende talked a lot about multi-tenant applications. In fact he explained my team how we could build such an application. The only thing lacking in Ayende's series of post was some real world examples. Let me try to fill that gap here. It is probably going to be a series of posts since we need to cover a couple of different issues here.
The plan is to add multi-tenancy to the WinecellarManager because then I don't have to start from scratch. For now I have the following posts in mind:
- How to deal with database customization: e.g. a tenant wants a new column in a given table.
- How to deal with differences in business logic?
- How to deal with differences in UI?
I don't know when I will be able to get these posts out but let's start with the first one. In this post we will deal with customizations of the domain model. Ayende dealt with it here. In our project we chose for a solution that the customization needs to be done by a developer because in the end we still want a rich domain model that does not kill you when you have to create reports on top of it. That's why we have a core domain model and tenants can have additions to the core.
It turns out that NHibernate is an excellent choice if you want to build multi tenant applications. In a previous post I already demonstrated one possibility. It is possible to override a complete mapping for a certain entity.
I'll demonstrate another possibility in this post. For one of my fake tenants I need to to have the possibility to keep a score for a wine. I'll start from the mapping for "Wines" and I added a discriminator to that mapping. It now looks like this:
Then I created a new class ParkerWine that looks like this:
The mapping for the ParkerWine class:
There is nothing more to it. You define ParkerWine as a "subclass" and tell NHibernate that it extends "Wine". Then you add the extra properties you need and you're done. Once you have done that you can start using ParkerWine in your app. I've created a very small demo console application that you can find here.