We're using tons of MEF in ASP.NET MVC, though most of it sits at a level below the controller level, as in our lower level modules use MEF plugins for checking permissions and validating data.
However, we also use a more composable approach to our controllers too. Views are more tricky, but we actually completely eliminated the use of regular ASP.NET MVC views and store our Razor views in snippets in a database. Our controllers then ask a template engine for a view at runtime and render ContentResult to the response instead of returning View("Viewname"), etc.
Our MEF plugins all carry identifier properties that let us do a cascading override at runtime to figure out which plugin/class should be used for a given purpose. The easiest example to demonstrate would be if you think about an app that has a common base, but is deployed to 50+ implementations that each have the option to override the core functionality.
So, you might have something like an IUserController that includes methods for "Login", "Logout", etc.
In addition to that actual functionality, we'd add a read-only GUID property to the interface called "SiteId". Each implementation would then hard-code the SiteId it's intended for. For the "default" implementation in the core code, it would return "Guid.Empty".
Then, when we invoke MEF and go looking for which implementation of IUserController to use, we'd do an ImportMany of all of them into a List and then use LINQ to query the properties to figure out which one to use:
var _currentUserController = _availableUserControllers.FirstOrDefault(
c=>c.SiteId == AppSettings.SiteId);
if(_currentUserController == null){
//There is no site-specific override
_currentUserController = _availableUserControllers.FirstOrDefault(
c=>c.SiteId == Guid.Empty);
}
To do this with controllers, your best bet is to look at some of the implementations of MEF-based controller factories out there on the web.
However, like I said, we do nearly all of this at a level that's lower and have our modules or the controllers do this kind of lookup to determine which plugins to run.