Last active
August 29, 2015 14:07
-
-
Save dealproc/8036162b4c566de2308b to your computer and use it in GitHub Desktop.
NHibernateSessionSource
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using NHibernate; | |
using NLog; | |
public class AccountAccessor : IAccountAccessor { | |
Logger Log = LogManager.GetCurrentClassLogger(); | |
ISessionFactory _SessionFactory; | |
public AccountAccessor(ISessionFactory sessionFactory) { | |
_SessionFactory = sessionFactory; | |
} | |
public Account GetCurrentAccount() { | |
using (var session = _SessionFactory.OpenSession()) { | |
var _AccountRepository = new AccountRepository(new UnitOfWork(session)); | |
string hostname = System.Web.HttpContext.Current.Request.Url.Host; | |
Log.Debug("Host name resolved from HttpContext.Current == {0}", hostname); | |
if (string.IsNullOrWhiteSpace(hostname)) { | |
throw new UnknownAccountException(1, "Could not resolve hostname from HttpContext.Current."); | |
} | |
var account = _AccountRepository.GetFirst(x => x.Hostname == hostname); | |
if (account == null) { | |
Log.Debug("Account was not found in system."); | |
throw new UnknownAccountException(2, string.Format("Hostname: {0} has not been registered.", hostname)); | |
} | |
Log.Debug("Associated Account Id/GUID: {0}/{1}", account.Id, account.GUID); | |
return account; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ClaimsPrincipalAccountAccessor : IAccountAccessor { | |
Logger Log = LogManager.GetCurrentClassLogger(); | |
ISessionFactory _SessionFactory; | |
public ClaimsPrincipalAccountAccessor(ISessionFactory sessionFactory) { | |
_SessionFactory = sessionFactory; | |
} | |
public Core.DataModel.Users.Account GetCurrentAccount() { | |
using (var session = _SessionFactory.OpenSession()) { | |
var _AccountRepository = new AccountRepository(new UnitOfWork(session)); | |
var principal = HttpContext.Current.User as ClaimsPrincipal; | |
if (principal == null) { | |
throw new SecurityException("User is unauthorized."); | |
} | |
try { | |
var accountClaim = principal.Claims.First(x => x.Type == Constants.ClaimTypes.TenantId); | |
var account = _AccountRepository.GetFirst(x => x.GUID == accountClaim.Value); | |
if (account == null) { | |
Log.Debug("Account was not found in the system."); | |
throw new UnknownAccountException(3, "Account cannot be found from hardware's claims."); | |
}; | |
Log.Debug("Associated Account Id/GUID: {0}/{1}", account.Id, account.GUID); | |
return account; | |
} catch (Exception) { | |
Log.Debug("User is not a hardware device. Throwing 'null' back to calling method."); | |
return null; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IAccountAccessor { | |
Account GetCurrentAccount(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface ISessionSource { | |
ISession CreateSession(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using System; | |
public class NHibernateMultitenantConfigModule : Module { | |
protected override void Load(ContainerBuilder builder) { | |
if (builder == null) { | |
throw new ArgumentNullException("builder"); | |
} | |
builder.Register<Account>(x => { | |
return x.Resolve<IAccountAccessor>().GetCurrentAccount(); | |
}); | |
builder.RegisterType<NHibernateSessionSource>() | |
.AsImplementedInterfaces() | |
.SingleInstance(); | |
builder.Register(c => { | |
var threadContext = c.Resolve<IComponentContext>(); | |
return new UnitOfWork(threadContext.Resolve<ISessionSource>().CreateSession()); | |
}) | |
.AsSelf() | |
.InstancePerRequest(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac.Features.OwnedInstances; | |
using FluentNHibernate.Automapping; | |
using FluentNHibernate.Cfg; | |
using FluentNHibernate.Cfg.Db; | |
using NHibernate; | |
using NHibernate.Caches.SysCache; | |
using NHibernate.Dialect; | |
using System; | |
using System.Collections.Generic; | |
using System.Configuration; | |
using System.Linq; | |
using Configuration = NHibernate.Cfg.Configuration; | |
public class NHibernateSessionSource : ISessionSource { | |
Dictionary<Account, ISessionFactory> _SessionFactories = new Dictionary<Account, ISessionFactory>(); | |
static readonly object _FactorySyncRoot = new object(); | |
string _ConnectionStringModel = ""; | |
Owned<IAccountAccessor> _AccountAccessor; | |
public NHibernateSessionSource(Owned<IAccountAccessor> accountAccessor) { | |
_AccountAccessor = accountAccessor; | |
_ConnectionStringModel = ConfigurationManager.ConnectionStrings["ClientDBTemplate"].ConnectionString; | |
} | |
public NHibernate.ISession CreateSession() { | |
var account = _AccountAccessor.Value.GetCurrentAccount(); | |
return GetSessionFactory(account).OpenSession(); | |
} | |
private Configuration BuildConfiguration(Account account) { | |
var rawConfig = new NHibernate.Cfg.Configuration(); | |
rawConfig.SetNamingStrategy(new PostgresqlNamingStrategy()); | |
var configuration = Fluently.Configure(rawConfig) | |
.Database( | |
PostgreSQLConfiguration.Standard | |
.Driver<ProfiledNpgsqlDriver>() | |
.Dialect<PostgreSQL82Dialect>() | |
.ConnectionString( | |
string.Format(_ConnectionStringModel, account.DatabaseName) | |
) | |
) | |
.ExposeConfiguration(c => c.SetProperty(NHibernate.Cfg.Environment.ReleaseConnections, "on_close")) | |
.ExposeConfiguration(c => c.SetProperty(NHibernate.Cfg.Environment.ShowSql, "false")) | |
.ExposeConfiguration(c => c.SetProperty(NHibernate.Cfg.Environment.UseSecondLevelCache, "true")) | |
.Cache(c => c.ProviderClass<SysCacheProvider>().UseQueryCache().UseSecondLevelCache()) | |
.Mappings(m => { | |
m.AutoMappings.Add( | |
AutoMap | |
.AssemblyOf<NHibernateConfigModule>(new AutomappingConfiguration()) | |
.UseOverridesFromAssemblyOf<Infrastructure.Mappings.ItemMapOverride>() | |
.Conventions.AddFromAssemblyOf<DateTimeOffsetValueConverter>() | |
.Conventions.AddFromAssemblyOf<Infrastructure.Conventions.HasManyToManyConvention>() | |
.IncludeBase<Core.DataModel.Transactions.TransactionPayment>() | |
); | |
}) | |
.BuildConfiguration(); | |
return configuration; | |
} | |
private ISessionFactory BuildSessionFactory(Configuration config) { | |
var sessionFactory = config.BuildSessionFactory(); | |
if (sessionFactory == null) { | |
throw new Exception("Cannot build NHibernate Session Factory"); | |
} | |
return sessionFactory; | |
} | |
private ISessionFactory GetSessionFactory(Account account) { | |
var accountSessionFactory = _SessionFactories.Where(kvp => kvp.Key.GUID == account.GUID).Select(x => x.Value).SingleOrDefault(); | |
if (accountSessionFactory == null) { | |
lock (_FactorySyncRoot) { | |
var cfg = BuildConfiguration(account); | |
accountSessionFactory = cfg.BuildSessionFactory(); | |
_SessionFactories.Add(account, accountSessionFactory); | |
} | |
} | |
return accountSessionFactory; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment