It depends on how you plan to implement multithreading (for example, using authorization with shared URLs, subdomains, user domains, or any combination). But you should be able to do almost any approach with Azure and MVC2. If you plan to use your own domain for each tenant compared to the subdomain, you will need to be content with using CNAME records (not A records) to point each user domain to Azure, but this is usually not a problem.
MVC offers many extension points where you can implement multithreading in your various options. The main goal is to uniquely identify the user with either a login or a URL.
We have an Azure-based MVC2 application that parses the request URL to differentiate the tenant. There are many ways to do this. We have adopted the Controller class extension approach to provide our application with unique tenant information so that we can use it as needed to make appropriate repository calls to display the corresponding views, etc.
Here is an example of what the MultiTenant Controller looks like:
public class MultiTenantController : Controller { public string TenantCode { get; set; } protected override void OnActionExecuting(ActionExecutingContext filterContext) { TenantCode = GetTenantCode(filterContext.HttpContext.Request); } private string GetTenantCode(System.Web.HttpRequestBase request) { string host = new RequestParser(request.Url.AbsoluteUri).Host; return _tenantService.GetTenantCodeByHostAddress(host); } }
NOTES:
- The RequestParser function above is just any implementation that knows how to parse URLs in a safe way.
- _tenantService can access some permanent store (Cote d'Azur in our case) before getting TenantCode from the host address in the URL.
All your controllers would inherit from the above class. Then, to distinguish between tenants, you simply reference TenantCode inside your controller:
public class HomeController : MultiTenantController { ... public ViewResult Index() { var vm = _homeService.GetHomePageViewModelForTenant(TenantCode); return View(vm); } }
Using the implementation above, you can serve different sites or data at the following URLs:
http://subtenant1.yourdomain.com
http://subtenant2.yourdomain.com
http://www.customtenantdomain.com
In your backend store (for example, in a table storage), you just need to cross-reference the hostnames with the tenant, as in the table below. In the above code, GetTenantCode will access the data.
HostName TenantCode ---------------------- -------------- subtenant1 Tenant1ID subtenant2 Tenant2ID www.customtenantdomain Tenant3ID
For www.customtenantantdomain.com to work, the tenant needs a CNAME record for www in their DNS records for customtenantdomain.com, which points to your Azure web role address.