Previously on the Multi Tenancy series:
- Multi Tenancy - Definition and scenario.
- Reviewing Litware HR - P&P Multi Tenancy Sample.
- Multi Tenancy - The Physical Data Model
- Multi Tenancy - Extensible Data Model
- Multi Tenancy - Extensible Behaviors
- Multi Tenancy - Development Structure
I have migrated the app. from ASP and the ASP approach was to have a completelly seperate code stream for every customer and a seperate DB strucutre.
This was quickly getting out of hand.
I migrated all code streams into one app and every tenant now has their own DB instance of the same schema.
I am loathe to go down the path of actually developing maintainable bits of work that are only applicable for one tenant.
The variability has to be controlled by configuration, DSLs or maybe even clever use of build scripts that all build from the same code base.
I want to explain something, because it appears I wasn't clear. I am not advocating creating completely separate code streams (interesting description) for each tenant. I want a shared core with the variability existing within the scope of each tenant. Like this example:
Most of the application is in the core, but each tenant can decide to override specific functionality on as needed basis.
The key part here is that we want to be able to have a coherent view of how each tenant behave. Trying to do this by configuration or clever build scripts is actively detracting from gaining that clear view. I want to be able to open a project and look at all the things that this tenant is doing that are different from the default approach. I don't want to hunt down what "pays_overtime" means for this customer, and whatever they remembered that the "pays_overtime" configuration value must always go with the VALIDATE_MAX_OVERTIME_HOURS build value.
Regarding scripting and DSL, I am going to touch on this in a separate post, indeed, this is one extremely interesting way of dealing with the problem, but it is not conceptually different than the approach of creating a separate project. You just change the compiler, not the approach (not quite accurate on the detail, I'll admit, but enough for high level view).
You should remember that adding variability is easy, just put an if statement there. Making sure that you can understand what is going on there is a much more complex task.
Of course, if I have a set of modifications that always go together, I will probably decide to make this explicit in my model, so now the path to create a tenant would be similar to this:
But my main concern is the maintainability of the system. As such, I want to make sure that the view I have on a tenant's application is as clear as possible, and not mired in admittedly clever tricks that will cause a lot of pain down the road.