我们将 NServiceBus 和 Ninject 用于多租户 SaaS 应用程序。
当用户访问我们的网站或 API 时,我们可以通过检查 HttpContext Request 对象的主机名、检索有关该帐户的各种设置(其中一个是我们应该连接的数据库)来确定用户连接到哪个帐户和请求的其余部分连接到正确的数据库(进行各种其他检查)。
在我们的 NSB Windows 服务中,我们没有共享上下文的概念,通过它我们可以确定要连接的主机数据库,因此我们在基本命令类上创建了一个属性,用于存储创建命令的帐户/数据库/信息。
当为传入消息构造消息处理程序时,依赖项之一是存储库,该存储库将它应该连接到的数据库的名称作为参数。
如前所述,Ninject 可以为 Web 请求访问 HttpContext 中的正确数据库,但对于 NSB 服务,消息本身包含我们只能在构造处理程序后访问的数据库详细信息,这显然会失败,因为它需要一个参数(即包含在消息中!)以成功构建存储库。鸡肉和鸡蛋:)
这是一个冗长的询问方式......
- 在 Ninject 创建周期期间是否可以访问消息的属性?
- 这感觉像是因为我的架构“错误”而很难解决的难题之一,是这样吗?
- 我想避免将公共属性放在像“SetDatabase”这样的存储库上,因为感觉它很容易被滥用/误解,并对用户数据造成严重破坏。
- 我还考虑过创建一个存储库工厂,Ninject 会使用它,但仍然不确定如何访问传入的消息属性。
提前致谢!
编辑解决方案
我最终使用了来自 Udi 和 Eben 答案的混合方法。
我为我的 API 消息使用了外出消息修改器,将客户的帐户名称添加到出站消息的标头(来自 HttpContext)。然后,按照 Udi 的建议,在 NSB Windows 服务中,我使用入站修改器来检查标头并提取帐户名称。
我还创建了两个接口实例,按照 Eben 的建议向我的存储库提供连接字符串/帐户详细信息。一种用于 Web 请求,一种 ThreadStatic 类型由传入的 mutator 设置,然后 Ninject 绑定用于 NSB 的 repo 实例化。
我不能将两者都标记为正确,抱歉 Eben!:)