Reputation: 842
I am moving an app from single tenant to multi-tenant. In the process, I added tenantId to all the required models and updated the database (Entity Framework 5).
However, I have all the repositories that need updating. First, I don't know how to get the current user id (then tenantId) in the Model Project (not dependent on WebSecurity, no httpContext).
Second, I don't want to have to do this ugly/expensive code in all my controllers. (Get UserId, make a database call to get the tenantId, then pass that to the Repository.)
public class PinTypeController : BaseController
{
private PinTypeRepository pinTypeRepo;
public PinTypeController()
{
UserRepository userRepo = new UserRepository();
UserProfile user = userRepo.GetById(WebSecurity.CurrentUserId);
this.pinTypeRepo = new PinTypeRepository(user.TenantId);
}
public ActionResult Index()
{
vmPinType vm = new vmPinType();
vm.NewPinType = new PinType();
vm.PinTypes = pinTypeRepo.GetAll();
return View(vm);
}
}
Is there a better way to store the tenantId in a way that I can access it from the Model Project and all my repositories?
Upvotes: 3
Views: 1395
Reputation: 2459
I would decouple where the tenant id is coming from, from the rest of your code, for example you could support multiple domains where one tenant is mapped to a domain.
In my project I defined an interface
interface ITenantProvider
{
Tenant Tenant { get; }
}
And the implementation:
class TenantProvider : ITenantProvider
{
Tenant Tenant
{
get
{
Tenant tenant = HttpContent.Current.Items["Tenant"] as Tenant;
if (tenant == null)
{
string domain = GetDomain();
tenant = TenantRepository.GetTenantByDomain(domain);
HttpContext.Current.Items["Tenant"] = tenant;
}
return tenant;
}
}
}
I cache the tenant in the items-dictionary, so I can access the tenant as often as I want per request and dont get any performane issues.
If each user has a custom tenant it is not a problem, because you just have to change the interface. You could also add more complex logic, e.g. in my frontend the tenant is defined by url and in the admin-area there is a route-parameter for the tenant-id.
Upvotes: 6