Posts

Showing posts from November, 2025

Nullable and Required Types

Introduction Since the introduction of nullable reference types in C#, and also with the required keyword, I sometimes see some confusion, which I'm going to address here. This is kind of back to basics, but, yet, here we are! ;-) Reference Types A reference type in C#/.NET is a type that: Are instantiated on the heap Are passed by reference (pointer) Can be null Are declared with the class keyword (can also be record , in latest versions) Meaning, for example, that we can have this (string is a reference type): string str = null; str = "Hello, referece types!"; Value Types On the other hand, value types : Are instantiated on the stack Are passed by value (copied on every method call) Cannot be null Always have a value Are declared using the struct , enum , or record struct keywords Implicitly inherit from System.ValueType Value types are numbers, booleans, bytes, characters, enumerations, and some basic structures such as DateTime , Guid , or T...

Multitenancy Techniques for the UI in ASP.NET Core

Introduction I've been writing some posts on multitenancy with ASP.NET Core. So far we have: Tenant identification Data filtering (for EF Core) UI customisation (this article) Business logic  This time I'm going to talk about the User Interface (UI) and give some suggestions for: Loading contents inside of a view conditionally per tenant Loading different views for different tenants Using code for making tenant-dependent choices We shall be referencing the same ITenantIdProvider abstraction shown before. All the views I'll be talking about are, of course, Razor views , which can be views in a MVC app or Razor Pages . Loading Different Views per Tenant Views are used to render HTML contents in a MVC project. The actual service that is responsible for locating the views files is IViewLocationExpander . We will implement our own version that sticks another path to the list of paths used to search for views (the original ones come from  RazorViewEngineOption...

Multitenancy Techniques for ASP.NET Core

Introduction This will be another post on the multitenancy subject. For now, I plan to write or already wrote: Tenant identification (this article) Data filtering (for EF Core) UI customisation Business logic If you've been following this blog, you know about data filtering with EF Core as an example. This time, I will focus on tenant identification. A tenant is identified by some id. It may have some data, configuration, etc, against it, but, for now, we just want to be able to identify who it is. Tenant Identification When it comes to identifying a tenant, there are some options: A query string parameter (mostly for testing) A route part An HTTP header A JWT token property A cookie Other options might include: Using the HTTP Host header and mapping it to a tenant Using the source IP for the request and mapping it to a tenant I won't cover these for now. A single tenant will be associated with a request, and it won't change during its pro...

Multitenancy Techniques for EF Core

Introduction Multitenancy is a hot topic, which I covered a few times on my old blog. I won't dwell on its concepts, but, instead, I will present ways to apply multitenancy to EF Core. When it comes to data, multitenancy means that we should only retrieve data for the current tenant. I will present three ways to obtain the tenant id from inside of a  DbContext , which can then be used to set up query filters, connection strings, or mapping configuration. Multitenancy in Databases So, as I blogged before, there are essentially three strategies for applying multitenancy to databases: Using a tenant column on tenant-aware tables and filter by it Using a different schema, meaning, tenant-aware tables will be duplicated in different schemas and for each request, one schema will be used Using different databases, one for each tenant, and, for each request, pick the right connection string There are obviously pros and cons to each approach, but I won't go through them now. Instead,...

ASP.NET Core API Versioning

Image
This was ported from my original blog post here . Introduction When you have an existing deployed REST API that you want to change, you generally need to be very careful. Why would you want to change it? There can be a number of reasons: Changes to the request contract (adding, removing or modifying request parameters) Changes to the response contract (same as above) Changes to the behaviour of the existing actions (they now do something slightly different) Changes to the HTTP methods that the existing actions accept (not so common) Changes to the HTTP return status codes … In a controlled environment, you can change at the same time the server and the client implementations, which means that you can update your clients accordingly, but, unfortunately, this is not always the case. Enter versioning! With versioned APIs, you can have multiple versions of your API, one that the legacy clients will still recognise and be able to talk to, and possibly one or more that are more suitable for ...