在ASP.NET MVC中的模型项目中访问TenantId

3

我正在将一个应用从单租户迁移到多租户。在此过程中,我向所有必需的模型添加了tenantId,并更新了数据库(使用Entity Framework 5)。

然而,我需要更新所有需要更新的存储库。首先,我不知道如何在Model项目中获取当前用户id(然后是tenantId)(不依赖于WebSecurity,没有httpContext)。

其次,我不想在所有控制器中都写这种复杂/昂贵的代码。(获取UserId,进行数据库调用以获取tenantId,然后将其传递给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);
    }
}

有没有更好的方法来存储tenantId,以便我可以从Model项目和所有仓库中访问它?

1个回答

6

我建议你将租户ID的来源与代码分离,例如,你可以支持多个域名,其中一个租户映射到一个域名。

在我的项目中,我定义了一个接口。

interface ITenantProvider
{
    Tenant Tenant { get; }
}

实现细节如下:

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;
        }
    }
}

我在items-dictionary中缓存租户,这样我可以在请求中随意访问租户,并且不会出现任何性能问题。

如果每个用户都有自定义租户,那就没有问题,因为只需更改接口即可。您还可以添加更复杂的逻辑,例如在我的前端中,租户由URL定义,在管理区域中,有一个租户ID的路由参数。


是的,我认为这就是我正在寻找的解决方案类型。那么你是在global.asax的session_start中填充它吗?如果它是httpContext的一部分,它是如何传递给Model项目的呢? - scojomodena
我使用Unity作为依赖注入框架,但您也可以手动创建租户提供程序并将其传递给您的模型。 开始会话时无需设置任何内容,只需创建一个新实例并将租户提供程序传递给您的模型,例如在控制器中。 租户每次请求计算一次。 - SebastianStehle
我得学习依赖注入。这是我一直想做的事情。感谢您的指导! - scojomodena

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接