目前他们使用传统的Windows桌面应用程序。当用户设置这个Windows程序时,他们使用用户名和密码登录。然后系统为他们显示所属机构的列表(通常只有一个,但一些"高级用户"可能属于几个)。他们选择一个机构,然后程序连接到正确的数据库。在会话的其余时间里,所有用户操作都将在该数据库上执行。
客户想要创建一个web应用程序,最终替换Windows程序(两者将同时运行一段时间)。一名开发人员正在使用Angular 5创建前端,而我正在ASP .Net Core 2.1中开发API。
因此,web应用程序将类似于Windows应用程序的功能。用户登录到web应用程序。消耗我的Web API的Web应用程序告诉API刚刚登录的是哪个用户。然后,API从存储这些数据的数据库检查此用户属于哪些机构。API将用户所属的机构列表返回给Web应用程序。用户在那里选择一个机构。从此时起,Web应用程序将在所有API调用的标题中包括此机构ID。当API接收到来自Web应用程序的请求时,它会根据请求头中的机构ID知道要使用哪个数据库。
希望这样讲述清楚了...
显然,这意味着我将不得不根据API需要连接的数据库动态更改DbContext的连接字符串。我一开始在控制器本身上实现这一点,并成功运行,但这将涉及到在所有控制器中进行大量复制和粘贴反模式。因此,我尝试将其移动到DbContext的OnConfiguring事件中。我认为最好的方法是创建一个DbContext工厂来创建DbContext,在其中使用适当的连接字符串。但是我有点迷茫。您看,当web应用程序调用Web API的端点(例如HTTP GET请求以获取账户列表)时,将触发Accounts控制器中的HttpGet处理程序。此操作方法然后读取机构ID头。但这一切都是在控制器上发生的...如果我从DbContext的OnConfiguring()事件中调用DbContext工厂,它将不得不将已在控制器中读取的机构ID发送到工厂,以便工厂知道要创建哪个连接字符串。我试图不使用全局变量来保持我的类松散耦合。
除非我在管道中运行某个服务,拦截所有请求,读取机构ID头,然后将其注入到DbContext构造函数中?不知道该如何实现...
总的来说,我有些迷茫。我甚至不确定这是否是正确的方法。我看过一些“多租户”示例,但老实说,我觉得它们有点难以理解,我希望现在能做一些更简单的事情,并且随着我对 .Net Core 的认识提高,我可以相应地改进代码。