Using CAP library in a multi-tenant application via SubscribeFilter
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 SubscribeFilter
by 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.