ASP.NET Architecture – Managing Extensibility in Multi-Tenant Systems

Architectureasp.netplugins

I've got a few big web based multi-tenant products now, and very soon I can see that there will be a lot of customizations that are tenant specific.

An extra field here or there, maybe an extra page or some extra logic in the middle of a workflow – that sort of thing.

Some of these customizations can be rolled into the core product, and that's great. Some of them are highly specific and would get in everyone else's way.

I have a few ideas in mind for managing this, but none of them seem to scale well. The obvious solution is to introduce a ton of client-level settings, allowing various 'features' to be enabled on per-client basis. The downside with that, of course, is massive complexity and clutter. You could introduce a truly huge number of settings, and over time various types of logic (presentation, business) could get way out of hand. Then there's the problem of client-specific fields, which begs for something cleaner than just adding a bunch of nullable fields to the existing tables.

So what are people doing to manage this? Force.com seems to be the master of extensibility; obviously they've created a platform from the ground up that is super extensible. You can add on to almost anything with their web-based UI. FogBugz did something similiar where they created a robust plugin model that, come to think of it, might have actually been inspired by Force. I know they spent a lot of time and money on it and if I'm not mistaken the intention was to actually use it internally for future product development.

Sounds like the kind of thing I could be tempted to build but probably shouldn't. 🙂

Is a massive investment in pluggable architecture the only way to go? How are you managing these problems, and what kind of results are you seeing?

EDIT: It does look as though FogBugz handled the problem by building a fairly robust platform and then using that to put together their screens. To extend it you create a DLL containing classes that implement interfaces like ISearchScreenGridColumn, and that becomes a module. I'm sure it was tremendously expensive to build considering that they have a large of devs and they worked on it for months, plus their surface area is perhaps 5% of the size of my application.

Right now I am seriously wondering if Force.com is the right way to handle this. And I am a hard core ASP.Net guy, so this is a strange position to find myself in.

Best Answer

I faced a similar problem, and I'll tell you how I went about resolving it.

  1. Firstly, there is a "core" library, or engine. This basically runs the show, much as you have already got figured out. It handles things common to every system, from rendering forms dynamical, user and account management, roles, you name it, it does it.

  2. Every part of the system is contained within a module. A module has dependencies (other modules that it depends on). For example, the "core" system has Security (users, groups, roles, password policies), Locale, (translations, countries, cultures), File Repository, Email, etc, etc. Each module defines itself using an xml file. The xml file basically specifies the schemas, tables, calculation classes, screen definitions etceteras. These are read in when the application starts if the file date has changed.

  3. Customer-specific modules have their own xml files and own DLL. It all plus in and functions accordingly and transparently with the rest of the system. Right down to replacing existing MVC views with custom ones, with custom code and custom view models.

  4. If a customer wishes to extend existing functionality, the xml/system provides a method where I can "derive" one module from another. The new module has all the existing functionality, but with the customer's specific requirements in a new DLL and with an extended XML file that can make the modifications. The Caveat is, they can't actually remove existing fields in this system ,but we can extend it and provide entirely new objects and functionality.