Reputation: 2513
Creating a multi-tenant asp.net mvc 3 app with single app instance/multiple databases per tenant. There will also be a separate 'master' database that will house tenant-specific info (enabled features, tenant db connection info etc). Newbie to both NHibernate & IOC (Castle Windsor) and used this tutorial to get a basic CRUD setup going.
The following is what I use (from above-mentioned tutorial) to 'use' 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>());
}
}
The approach I'm thinking of taking is that the application would look at the host header/url to determine the tenant and then query the 'master' db to get the respective tenant's database connection info. I'm guessing the approach I have to take is have a separate SessionFactory per client - only problem is I don't know how (and where) to integrate it. Would appreciate any help/pointers to get a better understanding of how to [a] resolve this problem [b] get a better understanding of how to use Castle Windsor. Apologies, as the castle site seems to be a great resource, but not easily understood by a newbie like me.
Thanks!
Environment: ASP.NET MVC 3, .NET 4, Castle Windsor + Fluent NHibernate + NHibernate (via NuGet)
Upvotes: 3
Views: 1829
Reputation: 27384
usually the approach that's taken is to have multiple session factories (one per tenant) and use IHandlersSelector
to pick the right one based on some data from the request.
Regarding the remark about documentation being not easily understood, we're keen to improve it if you'd like to point out parts that you found not too easy to follow.
Upvotes: 1