使用NHibernate+Castle Windsor实现多租户(单应用程序,多数据库)

3
创建一个多租户的asp.net mvc 3应用程序,每个租户只有一个应用程序实例/多个数据库。还将有一个单独的“主”数据库,其中将存储特定于租户的信息(启用的功能、租户数据库连接信息等)。我对NHibernate和IOC(Castle Windsor)都是新手,并使用此教程来建立基本的CRUD设置。
以下是我使用的内容(来自上述教程),用于“使用”NHibernate:
 public class PersistenceFacility : AbstractFacility
    {
        protected override void Init()
        {
            var config = BuildDatabaseConfiguration();

            Kernel.Register(
                Component.For<ISessionFactory>()
                    .UsingFactoryMethod(config.BuildSessionFactory),
                Component.For<ISession>()
                    .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
                    .LifeStyle.PerWebRequest);
        }

        private Configuration BuildDatabaseConfiguration()
        {
            return Fluently.Configure()
                .Database(SetupDatabase)
                .Mappings(m =>
                {
                    m.FluentMappings.AddFromAssemblyOf<SectionMap>()
                                    .Conventions.AddFromAssemblyOf<TableNameConvention>();
                })
                .ExposeConfiguration(ConfigurePersistence)
                .BuildConfiguration();
        }

        protected virtual AutoPersistenceModel CreateMappingModel()
        {
            var m = AutoMap.Assembly(typeof(EntityBase).Assembly)
                .Where(IsDomainEntity)
                .OverrideAll(ShouldIgnoreProperty)
                .IgnoreBase<EntityBase>();

            return m;
        }

        protected virtual IPersistenceConfigurer SetupDatabase()
        {
            return MsSqlConfiguration.MsSql2008
                .DefaultSchema("dbo") 
                .UseOuterJoin()
                .ProxyFactoryFactory(typeof(ProxyFactoryFactory))
                .ConnectionString(x => x.FromConnectionStringWithKey("MasterDB"))
                .ShowSql();
        }

        protected virtual void ConfigurePersistence(Configuration config)
        {
            SchemaMetadataUpdater.QuoteTableAndColumns(config);
        }

        protected virtual bool IsDomainEntity(Type t)
        {
            return typeof(EntityBase).IsAssignableFrom(t);
        }

        private void ShouldIgnoreProperty(IPropertyIgnorer property)
        {
            property.IgnoreProperties(p => p.MemberInfo.HasAttribute<DoNotMapAttribute>());
        }
    }

我考虑采取的方法是应用程序将查看主机头/ URL 来确定租户,然后查询“主”数据库以获取相应租户的数据库连接信息。 我猜我必须采取的方法是为每个客户端使用单独的 SessionFactory-唯一的问题是我不知道如何(在哪里)集成它。 希望获得任何帮助/指针,以更好地理解如何[a]解决此问题[b]更好地了解如何使用Castle Windsor。 对不起,因为城堡网站似乎是一个很好的资源,但对像我这样的新手来说并不容易理解。

谢谢!

环境:ASP.NET MVC 3、.NET 4、Castle Windsor + Fluent NHibernate + NHibernate(通过NuGet)

1个回答

1
通常采用的方法是为每个租户设置多个会话工厂,并使用 IHandlersSelector 根据请求中的某些数据选择正确的工厂。
关于文档不易理解的评论,如果您能指出您发现的不易理解的部分,我们很乐意改进。

IHandlerSelector看起来很不错,我也找到了Ayende和Mike Hadlow的帖子。但我仍然不确定如何使用它从主数据库获取特定于租户的数据库连接信息,然后使用它为该租户创建一个新的会话工厂,类似于您的“persistancefacility”为主数据库所做的操作。关于文档的评论,我认为提供更多详细信息和明确的实际示例可能会使IOC概念对新手更容易理解。谢谢! - seekay

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