Multi-tenancy in ASP.NET MVC - Why do we want it?

I'll be gratuitously "borrowing" a lot  of material from my DDD8 slides in this post, it seemed like the right thing to do given that this series is a write-up and then continuation of that talk.

When dealing with more than one customer in the desktop market, it is customary to have a single product which is extendable through the use of plug-ins and an API, and often you can leave it up to your consumer base to write those plug-ins and add to your product in a manner they see fit.

In the web world it's a bit different, and you don't typically get that kind of behaviour (Facebook applications may or may not count, depending on how you look at it).


In a simple world, you'll have a single product which is used directly off the shelf by multiple customers:

Single product

When building web applications for a varied and paying customer base, It is likely that you have customers that are fickle and will want things done their way.

It often does not make business sense to turn good business down, and the business is what pays the hungry developer and thus when you finally get a customer who wants things done differently,  the business tells the developer to jump and the business's required response is the proverbial "how high?".

Consider the above diagram then, and imagine Customer A asking for something 'just a little bit different' and think about what your options could be.

We'll get the obvious dusted out of the way first:

if( featureIsEnabled....)

When I switched to the above code as a slide in my multi-tenant talk, I was greeted with laughter, but we've all known products which have ended up with such delightful nuggets in them.
It's blindingly obvious that it's not the right solution, and that as you progress down the route of making further modifications for either Customer A, B or C you'll end up with an un-maintainable mess of switches and flags. 'Nuff said.


You could then decide that you're going to keep that customer as a new product in its own right - that would remove the need for all those on-off switches.

A bespoke copy

This should very obviously be a big no-no as maintaining that then bespoke product and keeping it up to date with any changes then made to your core product is going to be nothing more than a giant headache.
As you get more customers, the number of developers you'll need to hire will increase almost in direct proportion to the number of codebases you have to maintain!  (Again, I've seen this done - so don't think I'm just pointing out the obvious for the sake of it)

Let's move onto the more-often used approach, of branching from a base product for your different needs, and utilising the power of a source control system to keep changes in sync between your code-bases.

Branching as an alternative

Customer A can be kept up to date by merging changes from the core product, and Customer B/C can get additional features from Customer A's branch if and when they desire it.

At first glances, it seems like this solution fits our needs - and indeed it can work well in a lot of given  scenarios. The problem comes when you scale this solution up to more than this small example - as few of us are (un)lucky enough to be able to deal with only three customers and remain financially viable!

Here is a small example of 30 customers sharing 15 code-bases!

A mess of branching dependencies

Yowsers!
How do you keep track of who has what features?
How do you test all of those different branches of code?
How do you deploy those branches of code?
How do you make a new version of the product and serve it to a customer?
How many developers do you need to manage that process?

It's never as simple as it looks, and you end up with not only the above problems, but you end up with the additional problems of what happens when a branch becomes radically different and you're unable to merge changes around.
There is too much developer interaction here - and your skilled staff end up having to spend most of their time creating new branches/pushing changes around instead of spending their time doing what they're actually trained to do - writing code. 


Adding a new customer shouldn't be about changing code, it should be about manipulating configuration, and modifying a customer shouldn't be about changing code, it should also be about manipulating configuration. 

In other words, problems should only be solved once - and configuration should be used to give or take features to and from customers.

Enter multi-tenancy...

The core concept of a well written multi-tenant application is that you should have a single code base, and a number of configurations - where each configuration tells the runtime what functionality should be available and what the look/feel should be.

Before continuing, I'd like to define a few of the terms I'll be using throughout this series of blog entries.

  • Module: A discrete set of functionality
  • Theme: The look and feel
  • Configuration:  A selection of modules, and a single theme

This is a personal leaning, and I know that some people would set this up differently. Each to their own, we've got to draw lines somewhere!


Anyway - as far as I'm concerned, Multi-tenancy gives us some of the following benefits:

Deployment becomes a simple case of installing your application onto a server, and setting up the configurations for that application.

When a request comes in, context is determined by some means (auth credentials, the hostname, whatever), and the relevant configuration is selected from that context.

A single server serving multiple customers

This is a very simple way of working, and if you design your application correctly, it becomes obvious that your hosting/maintenance costs can be reduced.

You can have multiple servers with the exact same codebase installed on them, and with all the configurations available to them (In other words, identical).  Scaling up becomes a simple matter of adding more of those identical servers - and if you're really smart you can load balance across your VPSs and power them up/down as required.
You no longer need to worry (too much) about the fact that you have all of those customers, and you can concentrate on the health of your system as a whole.

Load balanced multi-tenant system


 Some more benefits:

  • You add a feature once, and deploy it to your customers through the use of configuration
  • You can fix a bug, and deploy the fix once 
  •  Potentially easy management of your infrastructure (This actually comes through good design, and multi-tenancy just aids in that goal)
  • Developers get to spend their time coding new features/fixing bugs
  • New customers can have a site created in minutes and start to give feedback immediately

Everybody is a winner and we all get to go home and have pie and punch.

In the next entry, things will hot up as I'll start to look at ASP.NET MVC and determine the components that we can use to aid us in creating a multi-tenant application.

 



   


Print | posted on Monday, February 01, 2010 10:10 PM

Feedback

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by Dele Sikuade at 2/3/2010 10:50 AM
Gravatar Nice concise explanation of why multi-tenant is the only (sensible) way forward for Software Houses. As a man who is currently involved in the building of a multi-tenant MVC application I look forward to the next article.

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by robashton at 2/3/2010 11:47 AM
Gravatar It's going to be a long(ish) series, as I don't want to dump it all out at once, and I want to spend time building up direction.

Stick with me, and in a couple of entries I'll start actually talking about code!

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by Kev Hunter at 2/3/2010 1:36 PM
Gravatar "When I switched to the above code as a slide in my multi-tenant talk, I was greeted with laughter"

It was laughter of recognition on my part Rob.

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by Brian Vallelunga at 2/3/2010 2:36 PM
Gravatar We're doing a basic multi-tenancy setup for our clients and I thought I'd share a trick. One of the wonderful benefits of MVC is the ability to use custom view engines. Ours searches for views in a client-specific set of folders and then if it doesn't find them, a default set of folders. This gives us the ability to customize a view per-client while still maintaining the same code base for everyone else.

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by robashton at 2/3/2010 3:25 PM
Gravatar I'm getting there, but views are only a small part of the story so I'm having to write it in chapters ;-)

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by Asad Ali Butt at 3/14/2010 7:29 PM
Gravatar great and very informative. do appriciate

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by Trent at 4/5/2010 12:23 PM
Gravatar hey Rob at the end of this series will you be compiling it into a PDF with source code??

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by robashton at 4/5/2010 12:34 PM
Gravatar Is it worth doing that?

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by Jamie at 6/8/2010 7:27 AM
Gravatar Hi Rob, just like to say this is a very interesting tutorial. We've done something similar at my work, we tried a few of the "workflow" technologies and MEF to support this but in the end, we went with a solution quite similar to yours. It has one fundamental flaw though, versioning. At the moment there is no way to support different versions of the assembly within the same process (without appdomain) and get the view and controllers to use that particular appdomain. I wondered whether you had come across the problem and had solved it?

Jamie

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by robashton at 6/8/2010 7:38 AM
Gravatar I'll disappoint you here and say that when I saw this as an issue, my solution was just to ensure that I never had different versions of assemblies.

If I deploy code for one tenant, I deploy the code for the rest of the tenants too and do a full build, so I never get version mismatches.

# re: Multi-tenancy in ASP.NET MVC - Why do we want it?

Left by Jamie at 6/8/2010 1:23 PM
Gravatar Ahh well. Our hope is to be able to run C# 3.5 and 4.0 side by side which would obviously be different versions of assemblies (with the ability to do it with third party products as well).

What we aren't wanting is to have an upgrade nightmare as a new "module" comes out, with other modules becoming incompatible. Module Isolation doesn't seem to be possible in MVC unfortunately.

Your comment:





 
Please add 4 and 2 and type the answer here:

Copyright © Rob Ashton

Design by Rob Ashton, Based On A Design By Bartosz Brzezinski