using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.ServiceModel; using System.Threading; using NHibernate; using NHibernate.Cfg; using log4net; using log4net.Appender; using log4net.Layout; using log4net.Repository.Hierarchy; using BS.Shared.Exceptions; using BS.Shared.Core; namespace BeWo.Data { public class WCFHibernateSessionManager { private static Dictionary _SessionFactories = new Dictionary(); private static object _Lock = string.Empty; private static readonly string _LogsDirectory = @"C:\BeWoPlaner\service\Host\logs"; //private static readonly ILog log = LogManager.GetLogger("WCFHibernateSessionManager"); public static ISession CurrentSession { get { return SessionOperationContextExt.Current?.Session; } private set { SessionOperationContextExt.Current.Session = value; } } private static ISessionFactory SessionFactory { get { try { Monitor.Enter(_Lock); if(!_SessionFactories.ContainsKey(MultitenancyOperationContextExt.Current.Tenant)) { #if DEBUG //TODO: wieder einkommentieren! var hierarchy = (Hierarchy)LogManager.GetRepository(); var logger = (Logger)hierarchy.GetLogger("NHibernate.SQL"); logger.AddAppender(new TraceAppender { Layout = new SimpleLayout() }); hierarchy.Configured = true; #endif _SessionFactories[MultitenancyOperationContextExt.Current.Tenant] = new Configuration().Configure(BS.Shared.Core.Utils.CreateSavePath(AppDomain.CurrentDomain.BaseDirectory, @"Multitenancy\" + MultitenancyOperationContextExt.Current.Tenant + ".config")).BuildSessionFactory(); } return _SessionFactories[MultitenancyOperationContextExt.Current.Tenant]; } catch(Exception e) { var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionFactoryError.txt"); if(Directory.Exists(_LogsDirectory)) { File.AppendAllText(Path.Combine(_LogsDirectory, "WCFSessionError.txt"), $"SessionFactory get {DateTime.Now:dd.MM.yyyy HH:mm:ss}" + "\n" + e.Message + "\n" + e.StackTrace); } Debug.WriteLine("<<<<< " + e.StackTrace + (e.InnerException != null ? e.InnerException.Message : string.Empty)); throw new FaultException(e.StackTrace + e.InnerException != null ? e.InnerException.Message : string.Empty); } finally { Monitor.Exit(_Lock); } } } public static void ResetAllSessionFactories() { try { String[] tenants = new String[_SessionFactories.Keys.Count]; _SessionFactories.Keys.CopyTo(tenants, 0); foreach (var item in tenants) { ResetSessionFactory(item); } _SessionFactories = new Dictionary(); } catch (Exception) { //ignore? } } public static void ResetSessionFactory(string tenant) { String t = tenant; if (String.IsNullOrEmpty(t)) t = MultitenancyOperationContextExt.Current.Tenant; if (_SessionFactories.ContainsKey(t)) { try { ISessionFactory fact = _SessionFactories[t]; if (!fact.IsClosed) { fact.Close(); } fact.Dispose(); } catch (Exception e) { //ignore exception?? throw e; } _SessionFactories.Remove(t); } } private static ISessionFactory RebuildSessionFactory() { ResetSessionFactory(MultitenancyOperationContextExt.Current.Tenant); return SessionFactory; } public static void CloseSession() { if (CurrentSession != null) { CurrentSession.Close(); CurrentSession.Dispose(); CurrentSession = null; } } public static ISession OpenSession() { try { if (!TenantExists()) { throw new BeWoInvalidOperationException(AppError.MultitenancyOperationTenantUnknown); } Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE"); //System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); CloseSession(); ISession session = SessionFactory.OpenSession(new UpdInsInterceptor()); if (session == null) { session = RebuildSessionFactory().OpenSession(new UpdInsInterceptor()); } CurrentSession = session; return CurrentSession; } catch (Exception e) { if (Directory.Exists(_LogsDirectory)) { File.AppendAllText(Path.Combine(_LogsDirectory, "WCFSessionError.txt"), $"OpenSession {DateTime.Now:dd.MM.yyyy HH:mm:ss}" + "\n" + e.Message + "\n" + e.StackTrace); } throw new FaultException(e.StackTrace + e.InnerException?.Message); } } public static bool TenantExists() { var tenant = MultitenancyOperationContextExt.Current?.Tenant ?? SessionFacade.Tenant; var path = BS.Shared.Core.Utils.CreateSavePath(AppDomain.CurrentDomain.BaseDirectory, @"Multitenancy\" + tenant + ".config"); return File.Exists(path); } } }