多租户架构和NHibernate

时间:2020-03-06 14:20:55  来源:igfitidea点击:

谁能最后向我解释,在NHibernate支持的域模型中实现透明,流畅的多租户功能支持的最佳策略是什么?

我正在寻找方法,如何保持域逻辑与多租户的东西尽可能隔离,例如通过TenantID进行过滤等

解决方案

Ayende有一些关于构建多租户应用程序的不错的博客文章。 NHibernate的使用方式将取决于我们要使用的多租户类型。

最简单的方法是为每个客户端使用不同的数据库。

以这种方式实现多租户可以使我们有效地编写单个租户应用程序,而仅在创建/检索会话时担心多租户。

我还没有深入研究细节(几个月后我需要做类似的事情),但是我认为管理会话连接到哪个数据库的最简单方法是通过可确定哪个连接的自定义ISessionFactory实现。使用(基于外部方面,例如请求url的主机部分)。

我在网上某处至少看到过一篇讨论此事的文章,但目前无法找到链接。

如果我们正在使用Castle Windsor,请查看NHibernate集成工具。这支持多个(命名)会话工厂的概念,这将使我们可以为每个客户端拥有一个会话工厂。集成工具提供了一个ISessionManager接口,该接口使我们可以在命名的会话工厂上打开会话(以及为Web应用程序提供按请求的会话语义)。任何需要访问会话的内容都可以简单地使用ISession构造函数参数,并且我们可以创建一个将ISessionManager用作构造函数参数的工厂。然后,工厂可以通过检查请求以确定应使用哪个命名会话工厂来在适当的命名会话工厂上打开会话。

最近,我也一直在为下一个项目进行深入研究。
我们可以实现自定义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);
        }

    }

希望这可以帮助。

有多种方法可以实现它,但是多租户问题比数据模型更深。我不喜欢插入产品,但是请到我工作的公司Apprenda来查看SaaSGrid。我们是一个云操作系统,允许我们编写单个租户SOA应用程序(随意使用NHibernate进行数据访问)并自动注入多租户进入应用。发布应用程序时,我们可以执行诸如选择数据模型(隔离数据库或者共享数据库)之类的操作,并且SaaSGrid将进行相应部署,并且应用程序将运行而无需任何代码更改,只需编写代码就好像是为单个租户编写代码一样!

使用共享模式方法要求我们用其他信息来拦截和修饰所有查询,以限制结果。

NHibernate提供了拦截器来执行此操作,NHibernate 2.0 Aplpha 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

我已经在此处为"多租户"方法撰写了博客,该方法并非在所有情况下都很理想,但是,它的确使我们无需使用第三方产品就可以很大程度上忘记多租户问题。