private void RunInBackground(Action<string> action)
		{
			var threadContext = new LogicalThreadContext();
			var value = threadContext.Get<string>(ItemKey);

			action(value);
		}
        /// <summary>
        /// Creates the message converter given its name in the application context.
        /// </summary>
        /// <param name="messageConverterObjectName">Name of the message converter object.</param>
        /// <returns>
        /// A IMessageConverter instance configured via the application context
        /// </returns>
        public IMessageConverter CreateMessageConverter(string messageConverterObjectName)
        {
            AssertUtils.ArgumentHasText(messageConverterObjectName, "MessgaeFormatterObjectName");
            IDictionary converters = LogicalThreadContext.GetData(CONVERTER_DICTIONARY_SLOTNAME) as IDictionary;

            if (converters == null)
            {
                converters = new Hashtable();
                LogicalThreadContext.SetData(CONVERTER_DICTIONARY_SLOTNAME, converters);
            }
            if (!converters.Contains(messageConverterObjectName))
            {
                IMessageConverter mc =
                    (IMessageConverter)
                    applicationContext.GetObject(messageConverterObjectName, typeof(IMessageConverter));
                if (applicationContext.ObjectFactory.GetObjectDefinition(messageConverterObjectName).IsSingleton)
                {
                    log.Warn("MessageConverter with name = [" + messageConverterObjectName + "] should be declared with singleton=false.  Using Clone() to create independent instance for thread local storage");
                    converters.Add(messageConverterObjectName, mc.Clone());
                }
                else
                {
                    converters.Add(messageConverterObjectName, mc);
                }
            }
            return(converters[messageConverterObjectName] as IMessageConverter);
        }
Пример #3
0
        /// <summary>
        /// For webapplications always
        /// <ul>
        /// <li>convert IResources using the current context.</li>
        /// <li>use "web" as default resource protocol</li>
        /// <li>use <see cref="HybridContextStorage"/> as default threading storage</li>
        /// </ul>
        /// </summary>
        static WebSupportModule()
        {
            s_log = LogManager.GetLogger(typeof(WebSupportModule));
#if NET_2_0
            // required to enable accessing HttpContext.Request during IHttpModule.Init() in integrated mode
            ContextHideRequestResponse = null;
            try
            {
                fiHideRequestResponse = typeof(HttpContext).GetField("HideRequestResponse", BindingFlags.Instance | BindingFlags.NonPublic);
//                fiHideRequestResponse.SetValue(HttpContext.Current, false);
                ContextHideRequestResponse = (fiHideRequestResponse != null)?new SafeField(fiHideRequestResponse):null;
            }
            catch (SecurityException sec)
            {
                s_log.Warn(string.Format("failed reflecting field HttpContext.HideRequestResponse due to security restrictions {0}", sec));
            }
#endif

            // register additional resource handler
            ResourceHandlerRegistry.RegisterResourceHandler(WebUtils.DEFAULT_RESOURCE_PROTOCOL, typeof(WebResource));
            // replace default IResource converter
            TypeConverterRegistry.RegisterConverter(typeof(IResource),
                                                    new ResourceConverter(
                                                        new ConfigurableResourceLoader(WebUtils.DEFAULT_RESOURCE_PROTOCOL)));
            // default to hybrid thread storage implementation
            LogicalThreadContext.SetStorage(new HybridContextStorage());

            s_log.Debug("Set default resource protocol to 'web' and installed HttpContext-aware HybridContextStorage");
        }
        /// <summary>
        /// Bind the given resource for teh given key to the current thread
        /// </summary>
        /// <param name="key">key to bind the value to</param>
        /// <param name="value">value to bind</param>
        public static void BindResource(Object key, Object value)
        {
            AssertUtils.ArgumentNotNull(key, "Key value for thread local storage of transactional resources must not be null");
            AssertUtils.ArgumentNotNull(value, "Transactional resource to bind to thread local storage must not be null");

            IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary;

            //Set thread local resource storage if not found
            if (resources == null)
            {
                resources = new Hashtable();
                LogicalThreadContext.SetData(resourcesDataSlotName, resources);
            }
            if (resources.Contains(key))
            {
                throw new InvalidOperationException("Already value [" + resources[key] + "] for key [" + key +
                                                    "] bound to thread [" + SystemUtils.ThreadId + "]");
            }
            resources.Add(key, value);
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Bound value [" + Describe(value) + "] for key [" + Describe(key) + "] to thread [" +
                          SystemUtils.ThreadId + "]");
            }
        }
        public void FallbackToDefault()
        {
            IDbProvider provider1 = DbProviderFactory.GetDbProvider("System.Data.SqlClient");

            provider1.ConnectionString = "connString1";
            IDbProvider provider2 = DbProviderFactory.GetDbProvider("System.Data.SqlClient");

            provider2.ConnectionString = "connString2";
            MultiDelegatingDbProvider multiDbProvider = new MultiDelegatingDbProvider();
            IDictionary targetDbProviders             = new Hashtable();

            targetDbProviders.Add("db1", provider1);
            targetDbProviders.Add("db2", provider2);
            multiDbProvider.DefaultDbProvider = provider1;
            multiDbProvider.TargetDbProviders = targetDbProviders;
            multiDbProvider.AfterPropertiesSet();

            MultiDelegatingDbProvider.CurrentDbProviderName = "db314";
            try
            {
                Assert.AreEqual("connString1", multiDbProvider.ConnectionString);
            }
            finally
            {
                LogicalThreadContext.FreeNamedDataSlot(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME);
            }
        }
        public void NoDefaultProvided()
        {
            IDbProvider provider = DbProviderFactory.GetDbProvider("System.Data.SqlClient");

            provider.ConnectionString = "connString1";
            MultiDelegatingDbProvider multiDbProvider = new MultiDelegatingDbProvider();
            IDictionary targetDbProviders             = new Hashtable();

            targetDbProviders.Add("db1", provider);
            multiDbProvider.TargetDbProviders = targetDbProviders;
            multiDbProvider.AfterPropertiesSet();
            try
            {
                Assert.AreEqual("connString1", multiDbProvider.ConnectionString);
                Assert.Fail("InvalidDataAccessApiUsageException should have been thrown");
            }
            catch (InvalidDataAccessApiUsageException exception)
            {
                Assert.AreEqual("No provider name found in thread local storage.  Consider setting the property DefaultDbProvider to fallback to a default value.", exception.Message);
            }
            finally
            {
                LogicalThreadContext.FreeNamedDataSlot(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME);
            }
        }
        /// <summary>
        /// Unbind a resource for the given key from the current thread
        /// </summary>
        /// <param name="key">key to check</param>
        /// <returns>the previously bound value</returns>
        /// <exception cref="InvalidOperationException">if there is no value bound to the thread</exception>
        public static object UnbindResource(Object key)
        {
            AssertUtils.ArgumentNotNull(key, "Key must not be null");

            IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary;

            if (resources == null || !resources.Contains(key))
            {
                throw new InvalidOperationException("No value for key [" + key + "] bound to thread [" +
                                                    SystemUtils.ThreadId + "]");
            }
            Object val = resources[key];

            resources.Remove(key);
            if (resources.Count == 0)
            {
                LogicalThreadContext.FreeNamedDataSlot(resourcesDataSlotName);
            }
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Removed value [" + Describe(val) + "] for key [" + Describe(key) + "] from thread [" +
                          SystemUtils.ThreadId + "]");
            }
            return(val);
        }
Пример #8
0
        /// <summary>
        /// Configures the current IHttpHandler as specified by <see cref="Spring.Web.Support.PageHandlerFactory" />. If the
        /// <see cref="Spring.Web.Support.PageHandlerFactory" /> is not executed for the current request and an instance of
        /// <see cref="Page" /> is served revalidate if the instance should be configured.
        /// </summary>
        private void OnConfigureHandler(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            HandlerConfigurationMetaData hCfg = (HandlerConfigurationMetaData)LogicalThreadContext.GetData(CURRENTHANDLER_OBJECTDEFINITION);

            if (hCfg != null)
            {
                // app.Context.Handler = // TODO: check, if this makes sense (EE)
                ConfigureHandlerNow(app.Context.Handler, hCfg.ApplicationContext, hCfg.ObjectDefinitionName, hCfg.IsContainerManaged);
            }
            else
            {
                Page page = app.Context.Handler as Page;
                if (!IsPageWithRouteHandler(page))
                {
                    return;
                }

                // In case of Routing pages are not handled by the PageHandlerFactory therefore no HandlerConfigurationMetaData
                // is set.
                IConfigurableApplicationContext applicationContext = (IConfigurableApplicationContext)WebApplicationContext.Current;
                string normalizedVirtualPath = WebUtils.GetNormalizedVirtualPath(page.AppRelativeVirtualPath);

                ControlInterceptor.EnsureControlIntercepted(applicationContext, page);
                ConfigureHandlerNow(page, applicationContext, normalizedVirtualPath, true);
            }
        }
        public void NoMatchingProviderDefinedInThreadLocalStorage()
        {
            IDbProvider provider = DbProviderFactory.GetDbProvider("System.Data.SqlClient");

            provider.ConnectionString = "connString1";
            MultiDelegatingDbProvider multiDbProvider = new MultiDelegatingDbProvider();
            IDictionary targetDbProviders             = new Hashtable();

            targetDbProviders.Add("db1", provider);
            multiDbProvider.TargetDbProviders = targetDbProviders;
            multiDbProvider.AfterPropertiesSet();
            try
            {
                MultiDelegatingDbProvider.CurrentDbProviderName = "db2";
                Assert.AreEqual("connString1", multiDbProvider.ConnectionString);
                Assert.Fail("InvalidDataAccessApiUsageException should have been thrown");
            }
            catch (InvalidDataAccessApiUsageException exception)
            {
                Assert.AreEqual("'db2' was not under the thread local key 'dbProviderName' and no default IDbProvider was set.", exception.Message);
            }
            finally
            {
                LogicalThreadContext.FreeNamedDataSlot(MultiDelegatingDbProvider.CURRENT_DBPROVIDER_SLOTNAME);
            }
        }
        /// <summary>
        /// Gets the target provider based on the thread local name "dbProviderName"
        /// </summary>
        /// <returns>The corresonding IDbProvider.</returns>
        protected virtual IDbProvider GetTargetProvider()
        {
            string dbProviderName = (string)LogicalThreadContext.GetData(CURRENT_DBPROVIDER_SLOTNAME);

            if (dbProviderName != null && targetDbProviders.Contains(dbProviderName))
            {
                return((IDbProvider)targetDbProviders[dbProviderName]);
            }
            //Fall back to default if available
            if (defaultDbProvider != null)
            {
                if (LOG.IsDebugEnabled)
                {
                    LOG.Debug("No DbProvider defined in thread local storage, falling back to use DefaultDbProvider.");
                }
                return(defaultDbProvider);
            }
            if (dbProviderName == null)
            {
                throw new InvalidDataAccessApiUsageException(
                          "No provider name found in thread local storage.  Consider setting the property DefaultDbProvider to fallback to a default value.");
            }
            throw new InvalidDataAccessApiUsageException("'" + dbProviderName + "'"
                                                         + " was not under the thread local key 'dbProviderName' and no default IDbProvider was set.");
        }
Пример #11
0
            /// <summary>
            /// Binds this
            /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/>
            /// instance to the thread local storage variable for the current thread and
            /// backs up the existing
            /// <see cref="Spring.Transaction.Interceptor.TransactionAspectSupport.TransactionInfo"/>
            /// object for the current thread.
            /// </summary>
            public void BindToThread()
            {
                // Expose current TransactionStatus, preserving any existing TransactionStatus
                // for restoration after this transaction is complete.
                TransactionInfo currentTransactionInfo = LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo;

                _oldTransactionInfo = currentTransactionInfo;
                LogicalThreadContext.SetData(CURRENT_TRANSACTIONINFO_SLOTNAME, this);
            }
Пример #12
0
        /// <summary>
        /// Return if deferred close is active for the current thread
        /// and the given SessionFactory.</summary>
        /// <param name="sessionFactory">The session factory.</param>
        /// <returns>
        ///     <c>true</c> if [is deferred close active] [the specified session factory]; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentNullException">If SessionFactory argument is null.</exception>
        public static bool IsDeferredCloseActive(ISessionFactory sessionFactory)
        {
            if (sessionFactory == null)
            {
                throw new ArgumentNullException("sessionFactory", "No SessionFactory specified");
            }
            IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary;

            return(holderDictionary != null && holderDictionary.Contains(sessionFactory));
        }
Пример #13
0
        /// <summary>
        /// 获取线程的WarehouseId
        /// </summary>
        /// <returns>get the warehouseId bounded to current thread.</returns>
        public static string GetCurrentThreadWarehouseId()
        {
            object warehouseId = LogicalThreadContext.GetData(CURRENT_WAREHOUSE_ID);

            if (warehouseId == null)
            {
                return(string.Empty);
            }
            return(warehouseId.ToString());
        }
Пример #14
0
 ///<summary>
 /// Configures the current IHttpHandler as specified by <see cref="Spring.Web.Support.PageHandlerFactory"/>.
 ///</summary>
 private void OnConfigureHandler(object sender, EventArgs e)
 {
     HandlerConfigurationMetaData hCfg = (HandlerConfigurationMetaData)LogicalThreadContext.GetData(CURRENTHANDLER_OBJECTDEFINITION);
     if (hCfg != null)
     {
         HttpApplication app = (HttpApplication)sender;
         // app.Context.Handler = // TODO: check, if this makes sense (EE)
         ConfigureHandlerNow(app.Context.Handler, hCfg.ApplicationContext, hCfg.ObjectDefinitionName, hCfg.IsContainerManaged);
     }
 }
Пример #15
0
        protected override void Given()
        {
            _context = new LogicalThreadContext();

            _context.Set("firstItem", "foo");
            _context.Set("secondItem", "fee");
            _context.Set("thirdItem", "foe");
            _context.Set("complexSerializableItem", new Serializable {
                Foo = "bar"
            });
        }
Пример #16
0
 /// <summary>
 /// Sets a flag, whether this scope is in "open" state on the current logical thread.
 /// </summary>
 private void SetOpen(bool isOpen)
 {
     if (isOpen)
     {
         LogicalThreadContext.SetData(ISOPEN_KEY, ISOPEN_KEY);
     }
     else
     {
         LogicalThreadContext.FreeNamedDataSlot(ISOPEN_KEY);
     }
 }
Пример #17
0
 /// <summary>
 /// Gets/Sets a flag, whether this scope manages it's own session for the current logical thread or not.
 /// </summary>
 /// <value><c>false</c> if session is managed by this module. <c>false</c> otherwise</value>
 private void SetParticipating(bool participating)
 {
     if (participating)
     {
         LogicalThreadContext.SetData(PARTICIPATE_KEY, PARTICIPATE_KEY);
     }
     else
     {
         LogicalThreadContext.FreeNamedDataSlot(PARTICIPATE_KEY);
     }
 }
 /// <summary>
 /// Deactivate transaction synchronization for the current thread.
 /// </summary>
 /// <remarks>
 /// Called by transaction manager on transaction cleanup.
 /// </remarks>
 /// <exception cref="System.InvalidOperationException">
 /// If synchronization is not active.
 /// </exception>
 public static void ClearSynchronization()
 {
     if (!SynchronizationActive)
     {
         throw new InvalidOperationException("Cannot deactivate transaction synchronization - not active");
     }
     if (LOG.IsDebugEnabled)
     {
         LOG.Debug("Clearing transaction synchronization");
     }
     LogicalThreadContext.FreeNamedDataSlot(syncsDataSlotName);
 }
Пример #19
0
 /// <summary>
 /// 把当前UnitOfWork压入当前线程的事务线中
 /// 如果当前线程中不存在事务栈,则创建事务栈,并把事务栈放入当前线程
 /// 否则从当前线程中取出栈,并把当前UnitOfWork压入栈中
 /// </summary>
 public static void Push(IUnitOfWork unitOfWork)
 {
     if (ThreadBoundUnitOfWorkStack == null)
     {
         var stack = new Stack <IUnitOfWork>();
         stack.Push(unitOfWork);
         LogicalThreadContext.SetData(UnitOfWorkStack, stack);
     }
     else
     {
         ThreadBoundUnitOfWorkStack.Push(unitOfWork);
     }
 }
 /// <summary>
 /// Process the xml file in the given location, and schedule all of the
 /// jobs defined within it.
 /// </summary>
 /// <param name="fileName">Name of the file.</param>
 /// <param name="systemId">The system id.</param>
 /// <param name="sched">The sched.</param>
 public virtual void ProcessFileAndScheduleJobs(string fileName, string systemId, IScheduler sched)
 {
     LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched);
     try
     {
         ProcessFile(fileName, systemId);
         ExecutePreProcessCommands(sched);
         ScheduleJobs(sched);
     }
     finally
     {
         LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler);
     }
 }
Пример #21
0
 /// <summary>
 /// Process the xml file in the given location, and schedule all of the
 /// jobs defined within it.
 /// </summary>
 /// <param name="fileName">Name of the file.</param>
 /// <param name="systemId">The system id.</param>
 /// <param name="sched">The sched.</param>
 public virtual async Task ProcessFileAndScheduleJobs(string fileName, string systemId, IScheduler sched)
 {
     LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched);
     try
     {
         await ProcessFile(fileName, systemId).ConfigureAwait(false);
         await ExecutePreProcessCommands(sched).ConfigureAwait(false);
         await ScheduleJobs(sched).ConfigureAwait(false);
     }
     finally
     {
         LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler);
     }
 }
        /// <summary>
        /// Activate transaction synchronization for the current thread.
        /// </summary>
        /// <remarks>
        /// Called by transaction manager at the beginning of a transaction.
        /// </remarks>
        /// <exception cref="System.InvalidOperationException">
        /// If synchronization is already active.
        /// </exception>
        public static void InitSynchronization()
        {
            if (SynchronizationActive)
            {
                throw new InvalidOperationException("Cannot activate transaction synchronization - already active");
            }
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Initializing transaction synchronization");
            }
            ArrayList syncs = new ArrayList();

            LogicalThreadContext.SetData(syncsDataSlotName, syncs);
        }
Пример #23
0
        /// <summary>
        /// Returns a new connection object to communicate with the database.
        /// Determine if there are currently thread-bound credentials, using them if
        /// available, falling back to the statically specified username and password
        /// (i.e. values of the properties 'Username' and 'Password') otherwise.
        /// The username and password will be concatenated on the connection string
        /// using string in the Separator property
        /// </summary>
        /// <returns>A new <see cref="IDbConnection"/></returns>
        public override IDbConnection CreateConnection()
        {
            string user = LogicalThreadContext.GetData(USERNAME) as string;
            string pass = LogicalThreadContext.GetData(PASSWORD) as string;

            if (user != null && pass != null)
            {
                return(DoCreateConnection(user, pass));
            }
            else
            {
                return(DoCreateConnection(username, password));
            }
        }
Пример #24
0
 /// <summary>
 /// Process the xml file in the given location, and schedule all of the
 /// jobs defined within it.
 /// </summary>
 /// <param name="fileName">Name of the file.</param>
 /// <param name="systemId">The system id.</param>
 /// <param name="sched">The sched.</param>
 /// <param name="overwriteExistingJobs">if set to <c>true</c> [over write existing jobs].</param>
 public virtual void ProcessFileAndScheduleJobs(string fileName, string systemId, IScheduler sched,
                                                bool overwriteExistingJobs)
 {
     LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched);
     try
     {
         ProcessFile(fileName, systemId);
         ScheduleJobs(ScheduledJobs, sched, overwriteExistingJobs);
     }
     finally
     {
         LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler);
     }
 }
Пример #25
0
        /// <summary>
        /// 从当前线程的UnitOfWork栈中移除顶部的对象
        /// 如果当前线程中不存在事务栈,则返回<see langword="null"></see>
        /// </summary>
        /// <returns>The UnitOfWork which at the top of Stack in the current thread.</returns>
        public static IUnitOfWork Pop()
        {
            if (ThreadBoundUnitOfWorkStack == null)
            {
                return(null);
            }
            IUnitOfWork unitOfWork = ThreadBoundUnitOfWorkStack.Pop();

            if (ThreadBoundUnitOfWorkStack.Count == 0)
            {
                LogicalThreadContext.FreeNamedDataSlot(UnitOfWorkStack);
            }
            return(unitOfWork);
        }
Пример #26
0
        /// <summary>
        ///Initialize deferred close for the current thread and the given SessionFactory.
        /// Sessions will not be actually closed on close calls then, but rather at a
        /// processDeferredClose call at a finishing point (like request completion).
        /// </summary>
        /// <param name="sessionFactory">The session factory.</param>
        public static void InitDeferredClose(ISessionFactory sessionFactory)
        {
            AssertUtils.ArgumentNotNull(sessionFactory, "No SessionFactory specified");

            log.Debug("Initializing deferred close of Hibernate Sessions");

            IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary;

            if (holderDictionary == null)
            {
                holderDictionary = new Hashtable();
                LogicalThreadContext.SetData(DeferredCloseHolderDataSlotName, holderDictionary);
            }
            holderDictionary.Add(sessionFactory, new ListSet());
        }
 /// <summary>
 /// Process the xml file in the given location, and schedule all of the
 /// jobs defined within it.
 /// </summary>
 /// <param name="stream">stream to read XML data from.</param>
 /// <param name="sched">The sched.</param>
 public virtual void ProcessStreamAndScheduleJobs(Stream stream, IScheduler sched)
 {
     LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched);
     try
     {
         using (var sr = new StreamReader(stream))
         {
             ProcessInternal(sr.ReadToEnd());
         }
         ExecutePreProcessCommands(sched);
         ScheduleJobs(sched);
     }
     finally
     {
         LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler);
     }
 }
Пример #28
0
 /// <summary>
 /// Process the xml file in the given location, and schedule all of the
 /// jobs defined within it.
 /// </summary>
 /// <param name="stream">stream to read XML data from.</param>
 /// <param name="sched">The sched.</param>
 public virtual async Task ProcessStreamAndScheduleJobs(Stream stream, IScheduler sched)
 {
     LogicalThreadContext.SetData(ThreadLocalKeyScheduler, sched);
     try
     {
         using (var sr = new StreamReader(stream))
         {
             ProcessInternal(await sr.ReadToEndAsync().ConfigureAwait(false));
         }
         await ExecutePreProcessCommands(sched).ConfigureAwait(false);
         await ScheduleJobs(sched).ConfigureAwait(false);
     }
     finally
     {
         LogicalThreadContext.FreeNamedDataSlot(ThreadLocalKeyScheduler);
     }
 }
Пример #29
0
        /// <summary>
        /// Close the given Session or register it for deferred close.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="sessionFactory">The session factory.</param>
        internal static void CloseSessionOrRegisterDeferredClose(ISession session, ISessionFactory sessionFactory)
        {
            IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary;

            if (holderDictionary != null && sessionFactory != null && holderDictionary.Contains(sessionFactory))
            {
                log.Debug("Registering Hibernate Session for deferred close");
                // Switch Session to FlushMode.NEVER for remaining lifetime.
                session.FlushMode = FlushMode.Never;
                Set sessions = (Set)holderDictionary[sessionFactory];
                sessions.Add(session);
            }
            else
            {
                CloseSession(session);
            }
        }
        /// <summary>
        /// Creates the message queue given its name in the application context.
        /// </summary>
        /// <param name="messageQueueObjectName">Name of the message queue object.</param>
        /// <returns>
        /// A MessageQueue instance configured via the application context
        /// </returns>
        public MessageQueue CreateMessageQueue(string messageQueueObjectName)
        {
            AssertUtils.ArgumentHasText(messageQueueObjectName, "DefaultMessageQueueObjectName");
            IDictionary queues = LogicalThreadContext.GetData(QUEUE_DICTIONARY_SLOTNAME) as IDictionary;

            if (queues == null)
            {
                queues = new Hashtable();
                LogicalThreadContext.SetData(QUEUE_DICTIONARY_SLOTNAME, queues);
            }
            if (!queues.Contains(messageQueueObjectName))
            {
                MessageQueue mq = applicationContext.GetObject(messageQueueObjectName) as MessageQueue;
                queues.Add(messageQueueObjectName, mq);
            }
            return(queues[messageQueueObjectName] as MessageQueue);
        }
        /// <summary>
        /// Register a new transaction synchronization for the current thread.
        /// </summary>
        /// <remarks>
        /// Typically called by resource management code.
        /// </remarks>
        /// <exception cref="System.InvalidOperationException">
        /// If synchronization is not active.
        /// </exception>
        public static void RegisterSynchronization(ITransactionSynchronization synchronization)
        {
            AssertUtils.ArgumentNotNull(synchronization, "TransactionSynchronization must not be null");
            if (!SynchronizationActive)
            {
                throw new InvalidOperationException("Transaction synchronization is not active");
            }
            ArrayList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as ArrayList;

            if (syncs != null)
            {
                object root = syncs.SyncRoot;
                lock (root)
                {
                    syncs.Add(synchronization);
                }
            }
        }
		static void RunActionInBackground(object state)
		{
			WriteThreadInfo();

			var action = state as Action<string>;
			var threadContext = new LogicalThreadContext();
			var context = threadContext.Get<string>(ItemKey);

			action(context);
		}