Recently, I’ve been working on a multi-tenancy project. Like most projects I tend to gravitate towards, it wasn’t that simple.
For those of you who know don’t know what that means, multi-tenancy is when an application is designed to be used by multiple companies/users at the same time, keeping all data separated from each other.
Typically if you want something like this done, you add a
ClientId or some other restriction to your Models to help identify which tenant that Thing belongs to.
In the world of Entity Framework, you’d probably do
Thing.Where(x => x.ClientId == clientId). You’d do this for each select statement, each update, and each delete to verify that the client that was logged in had the correct permissions to that resource. That’s boring, annoying, tedious and prone to errors.
Enter stage left comes Entity Framework interceptors. EF interceptors do what you’d expect them to do and intercept your EF queries before they hit the SQL server. Because they do this, it is possible to manipulate or log those queries.
Following some code by Charalampos Karypidis, I was able to get the basics setup. Because the rest of this article is an expansion of Charalampos’ code, I’ll not be reposting parts of his code that I didn’t change. You’ll want to go read and understand his article (or get the code on GitHub) before continuing.
Where I part from Charalampos’ code is where I think things get interesting. Charalampos’ setup involves using the interceptor to assign TenantId to the UserId. That’s all fine and well, but what if there is actually a group of individuals all utilizing the same Tenant?