> Mike Valenty

Bolt-on Multi-Tenancy in ASP.NET MVC With Unity and NHibernate: Part II – Commingled Data

| Comments

Last time I went over going from separate web applications per tenant to a shared web application for all tenants, but each tenant still had its own database. Now we’re going to take the next step and let multiple tenants share the same database. After we add tenant_id to most of the tables in our database we’ll need the application to take care of a few things. First, we need to apply a where clause to all queries to ensure that each tenant sees only their data. This is pretty painless with NHibernate, we just have to define a parameterized filter:

1
2
3
4
5
6
7
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

  <filter-def name="tenant">
    <filter-param name="id" type="System.Int32" />
  </filter-def>

</hibernate-mapping>

And then apply it to each entity:

1
2
3
4
5
6
7
8
9
10
11
12
<class name="User" table="[user]">

  <id name="Id" column="user_id">
    <generator class="identity" />
  </id>

  <property name="Username" />
  <property name="Email" />

  <filter name="tenant" condition="tenant_id = :id" />

</class>

The last step is to set the value of the filter at runtime. This is done on the ISession like this:

1
2
3
4
5
6
7
8
9
10
Container
    .RegisterType<ISession>(
        new PerRequestLifetimeManager(),
        new InjectionFactory(c =>
        {
            var session = c.Resolve<ISessionFactory>().OpenSession();
            session.EnableFilter("tenant").SetParameter("id", c.Resolve<Tenant>().Id);
            return session;
        })
    );

The current tenant comes from c.Resolve<Tenant>(). In order for that to work, you have to tell Unity how to find the current tenant. In ASP.NET MVC, we can look at the host header on the request and find our tenant that way. We could just as easily use another strategy though. Maybe if this were a WCF service, we could use an authentication header to establish the current tenant context. You could build out some interfaces and strategies around establishing the current tenant context, however for this article I’ll just bang it out.

1
2
3
4
5
6
7
8
9
10
11
Container
    .RegisterType<Tenant>(new InjectionFactory(c =>
    {
        var repository = c.Resolve<ITenantRepository>();

        var context = c.Resolve<HttpContextBase>();

        var host = context.Request.Headers["Host"] ?? context.Request.Url.Host;

        return repository.FindByHost(host);
    }));

Second, we have to set the tenant_id when new entities are saved. This is a bit more complicated with NHibernate and requires a bit of a concession in that we have to add a field to the entity in order for NHibernate to know how to persist the value. I’m using a private nullable int for this.

1
2
3
4
5
6
7
8
9
10
public class User
{
    private int? tenantId;

    public virtual int Id { get; set; }

    public virtual string Username { get; set; }

    public virtual string Email { get; set; }
}

It’s private because I don’t want the business logic to deal with it and it’s nullable because my tenant table is in a separate database which means I can’t lean on the data model to enforce referential integrity. That’s a problem because the default value for an integer is zero which could be happily saved by the database. By making it nullable I can be sure the database will blow up if the tenant_id is not set.

So, back to the issue at hand. The tenant_id needs to be set when the entity is saved. For this, I’m using an interceptor and setting the value in the OnSave method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MultiTenantInterceptor : EmptyInterceptor
{
    private readonly Func<Tenant> tenant;

    public MultiTenantInterceptor(Func<Tenant> tenant)
    {
        this.tenant = tenant;
    }

    public override bool OnSave(object entity... object[] state, string[] propertyNames...)
    {
        var index = Array.IndexOf(propertyNames, "tenantId");

        if (index == -1)
            return false;

        var tenantId = tenant().Id;

        state[index] = tenantId;

        entity
            .GetType()
            .GetField("tenantId", BindingFlags.Instance | BindingFlags.NonPublic)
            .SetValue(entity, tenantId);

        return false;
    }
}

This IInterceptor mechanism is a little wonky. If you change any data, you have to do it in both the entity instance and the state array that NHibernate uses to hydrate entities. It’s not a big deal, it’s just one of those things you have to accept like the fact that Apple and Google are tracking your every move via your smart phone. Oh, and the interceptor gets wired up like this:

1
2
3
4
5
6
7
8
9
10
11
Container
    .RegisterType<ISessionFactory>(
        new ContainerControlledLifetimeManager(),
        new InjectionFactory(c =>
        {
            return new NHibernate.Cfg.Configuration()
                .Configure()
                .SetInterceptor(new MultiTenantInterceptor(() => c.Resolve<Tenant>()))
                .BuildSessionFactory();
        })
    );

We’re almost done. There is one more case that needs to be handled. When NHibernate loads an entity by its primary key, it doesn’t run through the query engine which means the tenant filter isn’t applied. Fortunately, we can take care of this in the interceptor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MultiTenantInterceptor : EmptyInterceptor
{
    ...

    public override bool OnLoad(object entity... object[] state, string[] propertyNames...)
    {
        var index = Array.IndexOf(propertyNames, "tenantId");

        if (index == -1)
            return false;

        var entityTenantId = Convert.ToInt32(state[index]);

        var currentTenantId = tenant().Id;

        if (entityTenantId != currentTenantId)
        {
            throw new AuthorizationException("Permission denied to {0}", entity);
        }

        return false;
    }
}

That’s it. Have fun and happy commingling.

Bolt-on Multi-Tenancy in ASP.NET MVC With Unity and NHibernate

| Comments

The Mission:

Build a web application as though it’s for a single customer (tenant) and add multi-tenancy as a bolt-on feature by writing only new code. There are flavors of multi-tenancy, in this case I want each tenant to have its own database but I want all tenants to share the same web application and figure out who’s who by looking at the host header on the http request.

The Plan:

To pull this off, we’re going to have to rely on our SOLID design principles, especially Single Responsibility and Dependency Inversion. We’ll get some help from these frameworks:

Game on:

Let’s take a look at a controller that uses NHibernate to talk to the database. I’m not going to get into whether you should talk directly to NHibernate from the controller or go through a service layer or repository because it doesn’t affect how we’re going to add multi-tenancy. The important thing here is that the ISession is injected into the controller, and we aren’t using the service locator pattern to request the ISession from a singleton.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class UserController : Controller
{
    private readonly ISession session;

    public UserController(ISession session)
    {
        this.session = session;
    }

    public ActionResult Edit(int id)
    {
        var user = session.Load<User>(id);

        return View(user);
    }
}

Alright, now it’s time to write some new code and make our web application connect to the correct database based on the host header in the http request. First, we’ll need a database to store a list of tenants along with the connection string for that tenant’s database. Here’s my entity:

1
2
3
4
5
6
7
8
public class Tenant
{
    public virtual string Name { get; set; }

    public virtual string Host { get; set; }

    public virtual string ConnectionString { get; set; }
}

I’ll use the repository pattern here so there is a crisp consumer of the ISession that connects to the lookup database rather than one of the tenant shards. This will be important later when we go to configure Unity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class NHibernateTenantRepository : ITenantRepository
{
    private readonly ISession session;
    private readonly HttpContextBase context;

    public NHibernateTenantRepository(ISession session, HttpContextBase context)
    {
        this.session = session;
        this.context = context;
    }

    public Tenant Current
    {
        get
        {
            var host = context.Request.Headers["Host"];
            return FindByHost(host);
        }
    }

    public Tenant FindByHost(string host)
    {
        return session
            .Query<Tenant>()
            .SingleOrDefault(t => t.Host == host);
    }
}

So now we need a dedicated ISessionFactory for the lookup database and make sure that our NHibernateTenantRepository gets the right ISession. It’s not too bad, we just need to name them in the container so we can refer to them explicitly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Container
    .RegisterType<ISessionFactory>(
        "tenant_session_factory",
        new ContainerControlledLifetimeManager(),
        new InjectionFactory(c =>
            new NHibernate.Cfg.Configuration().Configure().BuildSessionFactory())
    );

Container
    .RegisterType<ISession>(
        "tenant_session",
        new PerRequestLifetimeManager(),
        new InjectionFactory(c =>
            c.Resolve<ISessionFactory>("tenant_session_factory").OpenSession())
    );

Container
    .RegisterType<ITenantRepository, NHibernateTenantRepository>()
    .RegisterType<NHibernateTenantRepository>(
        new InjectionConstructor(
            new ResolvedParameter<ISession>("tenant_session"),
            new ResolvedParameter<HttpContextBase>()
        )
    );

Hopefully that’s about what you were expecting since it’s not really the interesting part. The more interesting part is configuring the ISession that gets injected into the UserController to connect to a different database based on the host header in the http request. The Unity feature we’re going to leverage for this is the LifetimeManager. This is an often overlooked feature of IoC containers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Container
    .RegisterType<ISessionFactory>(
        new PerHostLifetimeManager(() => new HttpContextWrapper(HttpContext.Current)),
        new InjectionFactory(c =>
        {
            var connString = c
                .Resolve<ITenantRepository>()
                .Current
                .ConnectionString;

            return new NHibernate.Cfg.Configuration()
                .Configure()
                .SetProperty(NHibernate.Cfg.Environment.ConnectionString, connString)
                .BuildSessionFactory();
        }));

Container
    .RegisterType<ISession>(
        new PerRequestLifetimeManager(),
        new InjectionFactory(c => c.Resolve<ISessionFactory>().OpenSession())
    );

Here we’re using a custom PerHostLifetimeManager. This tells Unity to maintain a session factory per host. When Unity runs across a host it doesn’t have a session factory for, it will run the InjectionFactory block to create one using the connection string associated with that tenant.

Since multiple simultaneous requests will be trying to get and set values with the same key, we need to make sure our PerHostLifetimeManager is thread safe. That’s pretty easy since Unity comes with a SynchronizedLifetimeManager base class that takes care of the fact that Dictionary isn’t thread safe.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class PerHostLifetimeManager : SynchronizedLifetimeManager
{
    private readonly Func<HttpContextBase> context;
    private readonly IDictionary<string, object> store;

    public PerHostLifetimeManager(Func<HttpContextBase> context)
    {
        this.context = context;
        store = new Dictionary<string, object>();
    }

    protected override object SynchronizedGetValue()
    {
        var host = GetHost();

        if (!store.ContainsKey(host))
            return null;

        return store[host];
    }

    protected override void SynchronizedSetValue(object newValue)
    {
        store[GetHost()] = newValue;
    }

    private string GetHost()
    {
        return context().Request.Headers["Host"];
    }
}

So what did we accomplish? Well we didn’t touch any of our existing application code. We just wrote new code and through configuration we added multi-tenancy! That’s pretty cool, but was it worth it? Well, the goal in itself isn’t super important, but this exercise can certainly highlight areas of your codebase where you might be violating the single responsibility principle or leaking too many infrastructure concepts into your application logic.

Tamarack: Chain of Responsibility Framework for .NET

| Comments

The Chain of Responsibility is a key building block of extensible software.

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. – Gang of Four

Variations of this pattern are the basis for Servlet Filters, IIS Modules and Handlers and several open source projects I’ve had the opportunity to work with including Sync4J, JAMES, Log4Net, Unity and yes, even Joomla. It’s an essential tool in the OO toolbox and key in transforming rigid procedural code into a composable Domain Specific Language.

I’ve blogged about this pattern before so what’s new this time?

  1. The next filter in the chain is provided via a delegate parameter rather than a property
  2. The project is hosted on github
  3. There is a NuGet package for it

How does it work? It’s pretty simple, there is just one interface to implement and it looks like this:

1
2
3
4
public interface IFilter<T, TOut>
{
    TOut Execute(T context, Func<T, TOut> executeNext);
}

Basically, you get an input to operate on and a value to return. The executeNext parameter is a delegate for the next filter in the chain. The filters are composed together in a chain which is referred to as a Pipeline in the Tamarack framework. This structure is the essence of the Chain of Responsibility pattern and it facilitates some pretty cool things:

  • Modify the input before the next filter gets it
  • Modify the output of the next filter before returning
  • Short circuit out of the chain by not calling the executeNext delegate

Show me examples!

Consider a block of code to process a blog comment coming from a web-based rich text editor. There are probably several things you’ll want to do before letting the text into your database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public int Submit(Post post)
{
    var pipeline = new Pipeline<Post, int>()
        .Add(new CanoncalizeHtml())
        .Add(new StripMaliciousTags())
        .Add(new RemoveJavascript())
        .Add(new RewriteProfanity())
        .Add(new GuardAgainstDoublePost())
        .Finally(p => repository.Save(p));

    var newId = pipeline.Execute(post);

    return newId;
}

What about dependency injection for complex filters? Take a look at this user login pipeline. Notice the generic syntax for adding filters by type. Those filters are built-up using the supplied implementation of System.IServiceProvider. My favorite is UnityServiceProvider.

1
2
3
4
5
6
7
8
9
10
11
public bool Login(string username, string password)
{
    var pipeline = new Pipeline<LoginContext, bool>(serviceProvider)
        .Add<WriteLoginAttemptToAuditLog>()
        .Add<LockoutOnConsecutiveFailures>()
        .Add<AuthenticateAgainstLocalStore>()
        .Add<AuthenticateAgainstLdap>()
        .Finally(c => false);

    return pipeline.Execute(new LoginContext(username, password));
}

Here’s another place you might see the chain of responsibility pattern. Calculating the spam score of a block of text:

1
2
3
4
5
6
7
8
9
10
public double CalculateSpamScore(string text)
{
    var pipeline = new Pipeline<string, double>()
        .Add<SpamCopBlacklistFilter>()
        .Add<PerspcriptionDrugFilter>()
        .Add<PornographyFilter>()
        .Finally(score => 0);

    return pipeline.Execute(text);
}

Prefer convention over configuration? Try this instead:

1
2
3
4
5
6
7
8
public double CalculateSpamScore(string text)
{
    var pipeline = new Pipeline<string, double>()
        .AddFiltersIn("Tamarack.Example.Pipeline.SpamScorer.Filters")
        .Finally(score => 0);

    return pipeline.Execute(text);
}

Let’s look at the IFilter interface in action. In the spam score calculator example, each filter looks for markers in the text and adds to the overall spam score by modifying the result of the next filter before returning.

1
2
3
4
5
6
7
8
9
10
11
12
public class PerspcriptionDrugFilter : IFilter<string, double>
{
    public double Execute(string text, Func<string, double> executeNext)
    {
        var score = executeNext(text);

        if (text.Contains("viagra"))
            score += .25;

        return score;
    }
}

In the login example, we look for the user in our local user store and if it exists we’ll short-circuit the chain and authenticate the request. Otherwise we’ll let the request continue to the next filter which looks for the user in an LDAP repository.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class AuthenticateAgainstLocalStore : IFilter<LoginContext, bool>
{
    private readonly IUserRepository repository;

    public AuthenticateAgainstLocalStore(IUserRepository repository)
    {
        this.repository = repository;
    }

    public bool Execute(LoginContext context, Func<LoginContext, bool> executeNext)
    {
        var user = repository.FindByUsername(context.Username);

        if (user != null)
            return user.IsValid(context.Password);

        return executeNext(context);
    }
}

Why should I use it?

It’s pretty much my favorite animal. It’s like a lion and a tiger mixed… bred for its skills in magic. – Napoleon Dynamite

It’s simple and mildly opinionated in effort to guide you and your code into The Pit of Success. It’s easy to write single responsibility classes and use inversion of control and composition and convention over configuration and lots of other goodness. Try it out. Tell a friend.

A Custom HttpModule to Log Request Duration

| Comments

My application has logging of fine-grained operations, but I want to see the duration of the entire web request. The idea is to start a Stopwatch on the BeginRequest event and then log the elapsed time on the EndRequest event. I started by modifying the Global.asax to wire this up, but quickly got turned off because I was violating the Open-Closed Principle. I really just want to bolt-in this behavior while I’m profiling the application and then turn it off when the kinks are worked out. IIS has a pretty slick extension point for this sort of thing that let’s you hook into the request lifecycle events.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class RequestDurationLoggerModule : IHttpModule
{
    private const string ContextItemKey = "stopwatchContextItemKey";

    public void Init(HttpApplication application)
    {
        application.BeginRequest += (o, args) =>
        {
            application.Context.Items[ContextItemKey] = Stopwatch.StartNew();
        };

        application.EndRequest += (o, args) =>
        {
            var stopwatch = (Stopwatch)application.Context.Items[ContextItemKey];
            stopwatch.Stop();

            var logger = GetLogger(application);

            logger.Debug(
                "{0} -> [{1} ms]",
                application.Context.Request.RawUrl,
                stopwatch.ElapsedMilliseconds);
        };
    }

    private static ILogger GetLogger(HttpApplication application)
    {
        var serviceProvider = application as IServiceProvider;

        if (serviceProvider == null)
        {
            return new NullLogger();
        }

        return serviceProvider.GetService<ILogger>();
    }

    public void Dispose()
    {
    }
}

The only weird part here is getting a handle to the logger. I’m using an IoC container in my application, however I can’t tell IIS how to build up my RequestDurationLoggerModule, so I’m stuck using the Service Locator pattern. The container could be a singleton, but I don’t like singletons, so I implemented IServiceProvider in Global.asax instead. All that’s left now is wiring in the module. Since Cassini behaves like IIS6, you have to use the legacy style configuration, which looks like this:

1
2
3
4
5
  <system.web>
    <httpModules>
      <add name="..." type="MyApplication.RequestDurationLoggerModule, MyApplication"/>
    </httpModules>
  </system.web>

For IIS7 though, you add it like this:

1
2
3
4
5
  <system.webServer>
    <modules>
      <add name="..." type="MyApplication.RequestDurationLoggerModule, MyApplication"/>
    </modules>
  </system.webServer>

Finally, it’s time to run the application and see the total request duration logged.

A Proper Closure in C#

| Comments

You’ve seen code like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Order
{
    private ITaxCalculator taxCalculator;
    private decimal? tax;

    public Order(ITaxCalculator taxCalculator)
    {
        this.taxCalculator = taxCalculator;
    }

    public decimal CalculateTax()
    {
        if (!tax.HasValue)
        {
            tax = taxCalculator.Calculate(this);
        }

        return tax.Value;
    }

    ...
}

There are a few things to pick at. I’m looking at the member variable named tax that is null until you call CalculateTax for the first time. There isn’t anything to prevent the rest of the class from using the tax variable directly and possibly repeating the null check code in multiple places. I thought it would be fun to rewrite it using a closure. I don’t mean the kind of accidental closures we write with LINQ, but an honest to goodness proper closure.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Order
{
    public Order(ITaxCalculator taxCalculator)
    {
        CalculateTax = new Func<Func<decimal>>(() =>
        {
            decimal? tax = null;
            return () =>
            {
                if (!tax.HasValue)
                {
                    tax = taxCalculator.Calculate(this);
                }
                return tax.Value;
            };
        })();
    }

    public Func<decimal> CalculateTax { get; set; }

    ...
}

A closure is created around the tax variable so only the CalculateTax function has access to it. That’s pretty awesome. I wouldn’t have thought of using this technique before learning JavaScript all over again. It’s fun code to write, but it’s not going to get checked-in to source control. It’s basically a landmine for the next guy that has to make changes. The mental energy it takes to wrap your head around it is like listening to a joke with a really long setup and a lousy punch line. The solution is more complicated than the problem.

I still thought it was worth the mental exercise. Each language has its wheelhouse which makes a certain class of problems easy to solve. Admittedly this was a bit forced here, but opening your mind to other solutions may lead to a breakthrough solving a legitimately tough problem.