Multi Tenancy - Keep It Simple, REALLY Simple
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
- Multi Tenancy - Where do you put variability?
- Multi Tenancy - Scriptability and DSL
- Multi Tenancy - multi tenant apps and frameworks
One of the most common approaches for handling multi tenancy is composed of the following core ideas: Dynamic and Configurable.
You build the application to be dynamic, so you can change the entities layout, the UI look and feel, modify business logic using configuration, etc.
This is wrong!
This is wrong mainly because it is so bloody complex as an approach. Let us take the example of the UI, dynamic UI is fairly simple to start with. However, when you need to start considering things like validation, error handling, different field types, and so on, you get to realize that this is not really as simple as it seems.
Don't get me started on the 3 tables DB (tblEntities, tblFields, tblFieldValues) that get you so much dynamic it is dynamite.
The main issue is that trying to build something using this approach is just bloody hard. You have to keep the dynamicism of the application at mind at all point. Most of the time, you wouldn't even notice that your choice prevent you from applying the dynamicism in the app, but you are still paying the price for using this.
In many ways, it is similar to having VB.Net Option Implicit (If I got it right, the one where it doesn't give you a compilation error if you call non existing method, only at runtime). In fact, this is a great corollary. The VB.Net "dynamic" stuff is so limited that it is useless in most scenarios. Compare what you can do with a dynamic language like Python or Ruby vs. what you can do with VB.Net. There is very little value of having this option in VB.Net. It is usually a mine, not a feature. (Yeah, okay, it is really good feature if you are working with IDispatch, I know. Work with me here).
By the same token adding dynamic features to your application, runtime configurable and so on, will tend to be a mine more often than help.
My approach is quite different. Instead of trying to add configurability to the application, or adding dynamic behaviors, we can choose a static approach, one that allows use to make the best use of the tools and approaches that we have.
How do we get the variability that we need?
Oh, that is easy. Seams.
Each individual piece has no concept of dynamic / configuration / fubar. It is self contained and cohesive unit that can be combined with other pieces.
If I want to modify the behavior of the system, I can just plug in a new piece, and the entire machine keep on chugging along, without really noticing that the new Widgetometor is bright orange and flashing in Morse code.
Using this approach, we don't have to pay the price for using dynamic, configurable to the Nth degree. We can write the application as we would always will, and when variability calls...
Just plug the new stuff in.
Keep is simple, and keep it simple throughout!
Comments
Perhaps this is the next post, can you elaborate on the way you would accomplish this:
"just plug in a new piece, and the entire machine keep on chugging along"
Great series, Thanks.
I really liked this post, this is bit especially:
"Instead of trying to add configurability to the application, or adding dynamic behaviors, we can choose a static approach, one that allows use to make the best use of the tools and approaches that we have."
On a previous post I commented that the team I am working with want to do the whole "tblEntities", "tblAssociations" etc for a CMS. I much prefer the idea of creating something more concrete, with less meta that, leans on the existing tools and techniques we know and love.
I see that, as we enroll new clients, there will always be some customization needed to make the system meet their requirements, but 80% of the hard work is taken care of by the CMS, and at least we'll be working within our comfort zone.
Regarding Mikes post - this pluggable thing sounds similar to the "composition over inheritance" idea. Any parallels there?
Also, I think of Rails again, where I can simply type
class Employee
acts_as_tree
end
acts_as_tree is a plugin, and it gives the entity instant tree behaviour (Children/Parent etc).
Is it something like DotNetNuke? What about the database extension strategy, what do you do?
I´m mantaining and evolving a multi-tenant e-commerce catalog system, it has little variability between tenant requirements and, consequently, well defined extension points in it´s layers, so I guess it´s not big deal regarding extensibility.
We´re using an IoC framework -- Windsor, and tricks like a "TenantAwareComponentFactory" with the factory facility to switch tenant specific components -- and metadata is enough for most of my problems.
Great post series, thanks.
So far, I am speaking in broad details.
I will outline how I want to actually deal with it in the future.
For extesible DB, see the previous posts in the series.
In other words composite applications? and a well thought out SOA strategy?
In case you care, "Option Implicit" doesn't actually exist.
Option Explicit Off means "I don't want to think about local variables"
Option Strict Off means "I don't want to think about types"
I think that I mean Option Strict Off, then
I don't think it's T_H_A_T hard. Complex?, Yes... a little more work than usual? Yes..., but it's rather quite straight forward. Infact, I'm implementing this same exact strategy for one of my clients, and I haven't hit any "really hard", complexity, or maintainability problems yet.
Yes, I'd agree, dynamite is dangerous, but it can also help you move mountains.... depending on requirements and needs.
Brain,
The 3 table DB is dangerous. It will kill your perf in no time the moment you have real data there.
Dynamic UI isn't hard, when you start with. But then you have things like "customer A wants dates formatted YYYY-MM-DD" and "customer B wants textboxes to be capital", etc.
Comment preview