我正在构建一个多租户 MVC 应用程序,其中有一个应用程序池和一个数据库。我有一个 Tenant 表,我的每个模型都有一个 TenantId 标识。
每个租户都有一个字符串“Url”,用于标识用于访问该租户数据的完整 URL。
我可以使用以下(粗略的近似)从我的 BaseController 访问它:
HttpRequest request = HttpContext.Current.Request;
Uri requestUrl = request.Url;
_tenant = _tenantService.GetTenantByUrl(requestUrl);
现在,我需要将租户传递到服务层以执行业务逻辑。我可以做到这一点的一种方法是遍历所有服务(约 200 个方法)中的每一个方法并添加一个租户参数。我必须触及对服务层的每个调用,以及每个服务层方法。这会起作用,但它很乏味并且混淆了代码。
例如,我之前的一种方法:
public void DeleteUserById(int userId)
{
using (var db = CreateContext())
{
var user = db.Users.FirstOrDefault(u => u.UserId.Equals(userId));
InternalDeleteUser(db, user);
}
}
之后(如果我通过租户):
public void DeleteUserById(Tenant tenant, int userId)
{
using (var db = CreateContext())
{
var user = tenant.Users.FirstOrDefault(u => u.UserId.Equals(userId));
InternalDeleteUser(db, user);
}
}
我想要实现的目标(通过从我的 BaseController 设置租户,上一层):
public void DeleteUserById(int userId)
{
using (var db = CreateContext())
{
var user = _tenant.Users.FirstOrDefault(u => u.UserId.Equals(userId));
InternalDeleteUser(db, user);
}
}
有什么方法可以使用我的 BaseService (所有其他服务都继承自此)或其他模式从控制器定义租户,并让服务方法将其拾取,而不将其作为参数传递给每个人?这样我只需要触摸基本控制器(或者甚至可能是 global.asax),而不需要其他任何东西。
简而言之:如何通过从 MVC 控制器定义对象来使所有服务都可以访问该对象,而不将其直接传递给服务?