Subscribe to my blog

Multi-tenancy in ASP.NET MVC - Controller Actions (Part II)

Published on 2010-4-5

(Or a post-mortem examination of what MvcEx taught me about MVC frameworks)

Previous entries in the series

A long time overdue (our multi-tenant product is nearly ready for release woohoo!) - I'm going to write a bit more about compositing controllers from "action containers" - which is how my reference multi-tenancy framework (MvcEx) currently does things. I want to explain my motivation for attempting that solution and to give a few opinions on the suitability of MS MVC for the task of building multi-tenant applications in this way.

As outlined in the previous entry about controller actions, when building a multi-tenant and internally extensible application it is convenient that modules be able to contribute actions (or more importantly, override existing actions) to supplement the views exposed by those modules.

The solution in the previous entry was to select the appropriate controller based on the context of the current request, but I was curious as to whether a neater solution could be created within our chosen framework to separate our concerns into application concerns and module concerns:

If I was building an MVC framework from scratch, I wouldn't have built a framework that forced you to inherit from a base class (Controller), with all the baggage and responsibility in one place like that, but it works for a lot of people and a lot of applications so I can't really complain too much...

Anyway, we are using MS MVC and are therefore have to live with these design decisions and can work around them as best we can to achieve what we want(as we have been doing so for the past few entries in this series)

The application needs to be able to intercept each action, to perform custom logic on models which are being received/sent to the client, to handle controller-specific errors etc.

The modules simply need to be able to provide actions, and ideally should be bound to the behaviour of the entire application so you don't get unexpected happenings down the line when you've written your 20th module and wonder why it's not working quite right. (Forgot to inherit from the right base class etc etc...)

It turns out that none of this is particularly easy, and the MvcEx solution was to create a framework which scans for classes labelled as being action containers (something with an attribute of MvcExActionContainer("Name")), gather together its methods and create a controller which derived from an application provided Controller with all the relevant actions created on it.

This required a lot of Reflection.Emit (Fun!), but the other problems encountered were:

Even if we used MEF to do the work of compositing the controllers, we would still have the problem that we were trying to impose a manner of working to the MS MVC framework that the MS MVC framework is not really geared up to do! (in my opinion).

Summary

In summary, the way MvcEx does things was a bad decision, and I'll probably change it for the method the previous blog entry uses in the near future (Simply choosing the controller we want to use).

Although it's not ideal in so far as it doesn't solve the problems we have with the design of MS MVC,  if we go down the route of trying to hide our flawed framework with a load of abstractions (MVC Turbine etc), we end up in a situation where we might have been better off writing our own MVC framework or using something else more suited to the kind of applications we want to build. (Fubu MVC, Open Rasta, etc)

It is of course probably worth contributing to that particular discussion at the asp.net uservoice thread, as our best hope is that the MS MVC guys take note of the multi-tenancy discussion and give some love to the framework in that area.

Coming up...

With the blogging started up once more, I'll be continuing this series by delving into a few questions I've had on the subject of multi-tenancy regarding configuration, deployment, internalisation and a few other hurdles we've had to cross whilst building our multi-tenant software on top of MS MVC.


blog comments powered by Disqus

Gareth Mark Elms


Love this series it's helping me to understand Orchard CMS so thanks for sharing. Do you stand by the MvcEx project as is? Noticed it hasn't been updated since January

robashton


"Stand by it", we use it in our product at work, but I still just consider it to be a reference implementation of one way you could do pluggable controllers.It was a little bit too "pure" IMO, and an implementation where you simply "chose" which controller to use instead of crap loads of reflection would be a little more pragmatic :)I'm done with MS MVC for the longterm though, rather than move to MVC2/MVC3, when we upgrade, we'll be switching to Fubu, which will allow us to do a lot of this kind of thing out of the box.

mvcvm


In my research on MVC3 design for plugin modules, i became aware of your discussion of Multi-Tenancy design viz ASP.NET projects.I was a bit surprised for this reason:IIS like most web servers allow hosting of multiple sites with separate worker pools. Each site may be composed of modules from a common codebase as you require. I believe they will run in their own AppDomain which is good for privacy and isolation, and if not mistaken, it is even possible to compose two variant sites by pointing to selections of virtual directories, effectively sharing resources.What you are attempting may be attractive to a market segment, but they would be taking on risks to privacy, availability etcThis is not meant as a criticism, as your articles (I am yet to finish the series) are useful to me by being thought-provoking. It would be enlightening to hear your response. Thank you!