多租户架构和NHibernate

3

请问有没有人能最终解释一下,在NHibernate支持的域模型中实现透明流畅的多租户功能的最佳策略是什么?

我正在寻找一种方法,如何尽可能地将域逻辑与多租户相关内容(如按TenantID过滤)隔离开来。

6个回答

2
最简单的方法是为每个客户端使用不同的数据库。
以这种方式实现多租户,可以有效地编写单租户应用程序,并且只需要在创建/检索会话时关注多租户问题。
我还没有深入研究细节(我需要几个月后做类似的事情),但我认为管理会话连接到哪个数据库最容易的方法是通过自定义ISessionFactory实现,该实现可以确定使用哪个连接(基于外部因素,例如请求URL的主机部分)。
我曾经看到过至少一篇在互联网上讨论此问题的帖子,但我现在找不到链接了。
如果您正在使用Castle Windsor,请查看NHibernate集成工具。这支持多个(命名)会话工厂的概念,这将允许您每个客户端拥有一个会话工厂。集成设施提供了一个ISessionManager接口,它允许您在命名会话工厂上打开会话(以及为Web应用程序提供每个请求的会话语义)。任何需要访问会话的内容都可以简单地采用ISession构造函数参数,您可以创建一个工厂,该工厂采用ISessionManager作为构造函数参数。然后,您的工厂可以通过检查请求来确定应使用哪个命名会话工厂来打开适当的命名会话工厂上的会话。

1

最近我也一直在研究它,为我的下一个项目做准备。

你可以实现自定义的IConnectionProvider,并在配置中使用“connection.provider”进行注册。

我建议你从DriverConnectionProvider派生,并重写ConnectionString,而不是完全实现一个自定义的连接提供程序。

可以像这样实现:

    public class ContextualConnectionProvider : DriverConnectionProvider
    {

        protected override string ConnectionString
        {
            get
            {
                return GetCurrentTenantDatabaseConnectionStringInternally();
            }
        }

        public override void Configure(IDictionary<string, string> settings)
        {
            ConfigureDriver(settings);
        }

    }

希望这能有所帮助。

1

有许多方法可以实现它,但多租户问题远不止数据模型。我不想去推销产品,但是你可以看看我们公司Apprenda的SaaSGrid。我们是一个云操作系统,可以让你编写单租户SOA应用程序(可以随意使用NHibernate进行数据访问),自动将多租户注入到你的应用程序中。当你发布你的应用程序时,你可以选择数据模型(隔离数据库或共享),然后SaaSGrid会相应地部署,你的应用程序将不需要任何代码更改而运行 - 只需像为单个租户编写代码一样!


1
我已经在我的博客中分享了一个多租户的方案here, 这种方法并不适用于所有情况,但是它确实可以让你基本上忘记多租户问题而无需使用第三方产品。

1
链接似乎已经失效,该URL并没有提供足够的信息来找到其他资源。 - Boris Callens

0

使用共享模式需要你拦截并装饰所有查询,以附加信息来限制结果。

NHibernate提供了拦截器来实现这一点,自NHibernate 2.0 Alpha 1起,还提供了事件监听器。

请参阅http://elegantcode.com/2008/05/15/implementing-nhibernate-interceptors/http://www.codinginstinct.com/2008/04/nhibernate-20-events-and-listeners.html以了解更多信息。

此外,还可以查看Ayende的Rhino Security组件,因为他在其中做了很多工作,通过安全描述符修改查询以添加额外的限制。您可以在https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/security中浏览源代码。


0

Ayende有一些关于构建多租户应用程序的好博客文章。如何使用NHibernate取决于您选择的多租户类型。


嗯,我在谈论简单的共享数据库/模式方法:大多数表都有特殊的租户标识列。但在领域模型层面上,我不希望看到任何这些属性。 - noetic
嗯...在这种情况下,我不确定,但我知道NHibernate会话允许您设置过滤器,但我不确定它们的确切工作方式。我相信它们允许您运行查询并加载实体,而无需将过滤器放入查询本身中。这可能是您想要的。 - Gilligan

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