it:ad:unity:httpcontextlifetimemanager

IT:AD:NET:IoC:Unity:HttpContextLifetimeManager

Incredibly, Unity only offers a Thread based lifetime manager – which is not appropriate for Web Scenarios.

Either use Ninject (as it has one baked in), or use the following when registering Services.

Code:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Practices.Unity;

namespace XAct.Services.IoC
{
    /// <summary>
    /// An implementation of the Unity Lifetime Manager specifically for 
    /// Web scenarios.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Used by <see cref="XAct.Services.ServiceLocatorService"/> when 
    /// trying to register services by WebRequest.
    /// </para>
    /// </remarks>
    /// <internal>
    /// See: http://bit.ly/yyguHs
    /// </internal>
    public class HttpContextLifetimeManager :  PerThreadLifetimeManager, IDisposable
    {

        private readonly string _key = Guid.NewGuid().ToString();




        #region Constants

        /// <summary>
        ///   Class of constants used within the
        ///   <see cref = "Environment" />
        ///   class.
        /// </summary>
        public static class Constants
        {
            /// <summary>
            ///   Constant used to save the ApplicationName in the Request's hashtable.
            /// </summary>
            public const string ApplicationNameKey = "ApplicationName";

            /// <summary>
            ///   FQN of System.Web
            /// </summary>
            public const string SystemWebAssemblyString =
                "System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
        }

        #endregion

        /// <summary>
        /// Retrieve a value from the backing store associated with this Lifetime policy.
        /// </summary>
        /// <returns>
        /// the object desired, or null if no such object is currently stored.
        /// </returns>
        public override object GetValue()
        {
            if (HttpContext == null)
            {
                return base.GetValue();
            }
            return InnerDict[_key];
        }

        /// <summary>
        /// Remove the given object from backing store.
        /// </summary>
        public override void RemoveValue()
        {
            if (HttpContext==null)
            {
                base.RemoveValue();
                return;
            }
            InnerDict.Remove(_key);
        }
        
        /// <summary>
        /// Stores the given value into backing store for retrieval later.
        /// </summary>
        /// <param name="newValue">The object being stored.</param>
        public override void SetValue(object newValue)
        {
            if (HttpContext == null)
            {
                base.SetValue(newValue);
            }

            InnerDict[_key] = newValue;
        }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            RemoveValue();
        }

        private IDictionary InnerDict
        {
            get
            {
                const string key = "Unity.HttpContextLifetimeManager.Cache";
                IDictionary results = HttpContextItems[key] as IDictionary;

                if (results == null)
                {
                    results = new Dictionary<object, object>();

                    HttpContextItems.Add(key, results);
                }
                return results;
            }
        }

        ///<summary>
        ///  The HttpContext by Reflection 
        ///  (so that this assembly does not end up having a reference
        ///  to System.Web)
        ///</summary>
        public static object HttpContext
        {
            get
            {
                if (_cachedHttpContextPropertyInfo == null)
                {
                    const string path = "System.Web.HttpContext";
                    const string assemblyName = Constants.SystemWebAssemblyString;

                    const string contextPath = "Current";

                    Type type = Type.GetType(path + ", " + assemblyName, true, true);

                    if (type == null)
                    {
                        return null;
                    }


                    //get the HTTP context property info
                    _cachedHttpContextPropertyInfo = type.GetProperty(contextPath,
                                                                      (BindingFlags.Public | BindingFlags.Static));
                }
                //get a reference to the current HTTP context
                return _cachedHttpContextPropertyInfo.GetValue(null, null);
            }
        }
        private static PropertyInfo _cachedHttpContextPropertyInfo;


        /// <summary>
        /// Gets the items.
        /// </summary>
        public IDictionary HttpContextItems
        {
            get
            {
                if (HttpContext != null)
                {
                    IDictionary items = HttpContext.GetValue("Items") as IDictionary;
                    return items;
                }
                throw new Exception("No HttpContext to back HttpContextLifetimeManager");
            }
        }

    }
}
  • /home/skysigal/public_html/data/pages/it/ad/unity/httpcontextlifetimemanager.txt
  • Last modified: 2023/11/04 03:32
  • by 127.0.0.1