Using CAP library in a multi-tenant application via SubscribeFilter

Emre Teoman
Borda Technology

--

Cloud based Software as a Service (SaaS) products is getting popular every day, which makes the multitenancy becomes a critical part of the architecture. A multi-tenant application can be defined as software that can serve more than one customer. Although software instances are shared between tenants, customers must be isolated. A tenant should never have access to the information of another tenant. Isolation can be accomplished by keeping tenant information across the system. This article describes how to implement multitenancy in the CAP library used for event messaging.

Individual services in microservices can communicate to perform a single task. In multi-tenant applications, tenant information gets transferred along with other data in inter-service communication. According to the synchronous and asynchronous communication between the services, tenant information can be transmitted differently. For example, if there is REST communication between two services, tenant information can be passed via the request header. Please look to the article Authorization header propagation in ASP.NET Core APIs which expresses how header propagation in .NET Core apps can be handled for authorization header.

On the other hand, event-base messaging is widely used as an asynchronous communication method. CAP is one of the libraries that has successfully implemented the event base communication for .NET Core. You can check the implementation example in our article Event bus implementation using EF Core and CAP libraries. Currently, CAP does not support multi-tenancy. This article aims to show how to develop a multi-tenant application using the filters in the CAP library.

Subscribe filter in CAP

To begin, let’s recap the subscribe filter structure.

Subscriber filters are similar to ASP.NET MVC filters and are mainly used to process additional work before and after the subscriber method is executed. Such as transaction management or logging, etc.

Creating and using a subscribe filter is easy to use. For example:

public class MyCapFilter: SubscribeFilter
{
public override void OnSubscribeExecuting(ExecutingContext ctx)
{
// before subscribe method exectuing
}
public override void OnSubscribeExecuted(ExecutedContext ctx)
{
// after subscribe method executed
}
public override void OnSubscribeException(ExceptionContext ctx)
{
// subscribe method execution exception
}
}

Currently, CAP does not support adding multiple filters. It can be added like that:

services.AddCap(opt => 
{
// ***
}.AddSubscribeFilter<MyCapFilter>();

Enabling the use of multiple filters

We can create several interceptors with a single SubscribeFilterby leveraging dependency injection. Let’s start with creating an abstract base class for interceptors.

In our application, EventBusInterceptorFilter will be the single filter.
However, it will allow for the development of multiple interceptors. Check the code below:

Creating basic Tenant Service

Let’s create a basic tenant service to proof of concept. It contains only TenantId to represent the tenant of the user. Tenant service should be registered as scoped service.

Next up is to write an interceptor for tenant service. OnSubscribeExecuting method is enough to show logic. Within this method, tenantId is obtained from the headers of the delivered message.

Registering Services in Startup

The code below shows how services and filters are registered basically. EventBusInterceptorFilter is added as a single subscribe filter. TenantService and TenantServiceEventBusInterceptor are added as scoped services. InMemoryStorage and InMemoryMessageQueue are used to keep the example simple.

Sample Application

You can access a sample application that implements all of the structures mentioned above in the link below.

TestController has two methods to simulate publishing and subscribing to an event. Publish method publishes an event with the header containing a tenant id. Subscribe methods logs the arrived message and tenant id set in publish method.

Event bus related articles in our publication

You can check our previous publications about CAP library and event bus implementations.

Thanks for reading.

--

--