Search code examples
asp.net-mvc-3dependency-injectionautofacdependency-resolver

Multi-tenant application with MVC 3 and DI


I've got an MVC application split into a few areas:

+ Root
+ -- Areas
   --+ US
     + -- USCodeController : XXXCodeBaseController
   --+ UK
       -- UKCodeController : XXXCodeBaseController
   --+ (Other countries pending)
+ -- Controllers
   --+ XXXCodeBaseController

So I've defined some base functionality in the Controllers folder and then inherited and extended the functionality in the areas folder. This way UI's can be customised around UI components specific for each country, workflow etc.

When it comes to using Autofac, what I am having to do is pass the IComponentContext up to the constructor parameter, which isn't very good. The problems include:

  1. When using true IoC, I need the IXXXServices injected, so I get an area specific class instead of the Autofac IComponentContext
  2. Each area is associated with a different database, but a shared schema - therefore using the same EF library, only with a different connection string.

The design should definitely be more elegant by injection services directly - which is what I am after. But the resolver doesn't seem to be flexible enough to resolve the controllers without a massive hack that is becoming quite a large wireup for every controller used. Here is an example of if you wire up a controller manually:

 builder.Register(s => new OrderService(r.ResolveNamed<IOrderRepository>("US"))
        .Named("US")
        .InstancePerHttpRequest();

 // Lets say we add a DeclinedOrderController

 public class DeclinedOrderControllerBase
 {
     public DeclinedOrderControllerBase ( IDeclinedOrderService service )
     { }
 }

To get the hook up working, you need the registration added to the Autofac, as we need a US/UK specific connection string in the DeclinedOrderService

     builder.Register(s => new DeclinedOrderController(r.ResolvedName<IDeclinedOrderService>("US")
        .Named("US")
        .InstancePerHttpRequest();

My question is (finally):

  • Is there a way to dynamically select a set of mapped Autofac registrations by the area, which will automatically resolve to new controllers?

Solution

  • I wanted to recommend a custom LifetimeScope per area, but it seems that there is an existing solution.

    Take a look at this: https://code.google.com/p/autofac/wiki/MultitenantIntegration.