Jeff
Jeff

Reputation: 36553

Isolation in a Multi-tenant ASP .NET Application

I'm building a multi-tenant ASP .NET application. Given that each tenant can configure their application dynamically (which may involve dynamic custom assemblies being loaded into memory), I need a means of isolating each tenant.

I'd prefer not to create a new Web Application per tenant for maintenance reasons.

I've was considering using the AppDomainManager to create an AppDomain per application, but it seems this is not intended to be used for ASP .NET applications.

Does anyone have some suggestions on this subject?

Thanks.

Upvotes: 13

Views: 2743

Answers (3)

Jakub Konecki
Jakub Konecki

Reputation: 46008

I wrote multi-tenant web application in MVC2. Adding / Removing an account is as complex as adding / removing a row in a table as I opted for shared database, shared schema approach.

This is a very good article about multi-tenant database design from MSDN: Multi-Tenant Data Architecture

All I had to do in MVC is to set up routing properly, so the first part of the path is account name:

  • www.yourdomain.com/Account1/...
  • www.yourdomain.com/Account2/...
  • www.yourdomain.com/Account3/...

and I have a custom MvcHandler for looking up account for each request:

public class AccountMvcHandler : MvcHandler
{
    public AccountModel Account { get; set; }

    public AccountMvcHandler(RequestContext requestContext)
        : base(requestContext)
    {
    }

    protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
    {
        string accountName = this.RequestContext.RouteData.GetRequiredString("account");
        Account = ServiceFactory.GetService<IAccountService>().GetAccount(accountName);

        // URL doesn't contain valid account name - redirect to login page with Account Name textbox
        if (Account == null)
            httpContext.Response.Redirect(FormsAuthentication.LoginUrl);

        return base.BeginProcessRequest(httpContext, callback, state);
    }
}

As it was said by Andreas Paulsson the key phrase is "custom assemblies". Why do you need 'custom assemblies' for configuration? Are you using CodeEmit? Will users upload them? I would rather think about using Windows Workflow Foundation for any client-specific business logic customisation.

Upvotes: 1

Rahul Soni
Rahul Soni

Reputation: 4968

When you create different web sites, your URL root is definitely gonna change. I was thinking why not different applications inside the main application, and put them in different Application Pools if required?

One... That way, the root URL would remain the same. Two... Creation a VDir or an instance of an application. Which one needs to be dynamic? Three... I've no expertise.

If I had to share the Pages, [based on applications hosted in different VDir], I would go for creating a new VDir for all my shared pages. And use some custom code to show application related data.

Upvotes: 1

Dave Markle
Dave Markle

Reputation: 97671

I guess the question is: If you aren't into creating a Web Application, then what type of isolation is really acceptable to you?

If you really want an OS-level guarantee that assemblies won't trod on one another, I would give each their own Web Application. This is especially true if you're allowing people to load third-party assemblies, and is super-especially true if those third-party assemblies can find ways to instantiate unmanaged code.

I can see not creating a separate Web Application if it's all your (managed) code, but once you put dynamic custom assemblies into the mix, I think it's the only way to go.

Upvotes: 5

Related Questions