File: httpstaticobjectscollection.cs
Project: ndp\fx\src\xsp\system\Web\System.Web.csproj (System.Web)
//------------------------------------------------------------------------------
// <copyright file="httpstaticobjectscollection.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
//------------------------------------------------------------------------------
 
/*
 * Static objects collection for application and session state
 * with deferred creation
 */
namespace System.Web {
    using System.Runtime.InteropServices;
 
    using System.Collections;
    using System.Collections.Specialized;
    using System.IO;
    using System.Web;
    using System.Web.Util;
    using System.Security.Permissions;
 
    //
    // Static objects collection class
    //
 
    /// <devdoc>
    ///    <para>Provides a static objects collection for the 
    ///       HTTPApplicationState.StaticObjects and TemplateParser.SessionObjects properties.</para>
    /// </devdoc>
    public sealed class HttpStaticObjectsCollection : ICollection {
        private IDictionary _objects = new Hashtable(StringComparer.OrdinalIgnoreCase);
 
 
        /// <devdoc>
        ///    <para>
        ///       Initializes a new instance of the <see cref='System.Web.HttpStaticObjectsCollection'/>
        ///       class.
        ///     </para>
        /// </devdoc>
        public HttpStaticObjectsCollection() {
        }
 
        internal void Add(String name, Type t, bool lateBound) {
            _objects.Add(name, new HttpStaticObjectsEntry(name, t, lateBound));
        }
 
        // Expose the internal dictionary (for codegen purposes)
        internal IDictionary Objects {
            get { return _objects;}
        }
 
        /*
         * Create a copy without copying instances (names and types only)
         */
        internal HttpStaticObjectsCollection Clone() {
            HttpStaticObjectsCollection c = new HttpStaticObjectsCollection();
 
            IDictionaryEnumerator e = _objects.GetEnumerator();
 
            while (e.MoveNext()) {
                HttpStaticObjectsEntry entry = (HttpStaticObjectsEntry)e.Value;
                c.Add(entry.Name, entry.ObjectType, entry.LateBound);
            }
 
            return c;
        }
 
        /*
         * Get number of real instances created
         */
        internal int GetInstanceCount() {
            int count = 0;
 
            IDictionaryEnumerator e = _objects.GetEnumerator();
 
            while (e.MoveNext()) {
                HttpStaticObjectsEntry entry = (HttpStaticObjectsEntry)e.Value;
 
                if (entry.HasInstance)
                    count++;
            }
 
            return count;
        }
 
 
        /// <devdoc>
        /// </devdoc>
        public bool NeverAccessed {
            get {return (GetInstanceCount() == 0);}
        }
 
        //
        // Implementation of standard collection stuff
        //
 
 
        /// <devdoc>
        ///    <para>Gets the object in the collection with the given name (case 
        ///       insensitive). </para>
        /// </devdoc>
        public Object this[String name]
        {
            get {
                HttpStaticObjectsEntry e = (HttpStaticObjectsEntry)_objects[name];
                return(e != null) ? e.Instance : null;
            }
        }
 
        // Alternative to the default property
 
        /// <devdoc>
        ///    <para>Gets the object in the collection with the given name 
        ///       (case insensitive). Alternative to the <paramref name="this"/> accessor.</para>
        /// </devdoc>
        public Object GetObject(String name) {
            return this[name];
        }
 
 
        /// <devdoc>
        ///    <para>Gets the number of objects in the collection.</para>
        /// </devdoc>
        public int Count {
            get {
                return _objects.Count;
            }
        }
 
 
        /// <devdoc>
        ///    <para>Returns a dictionary enumerator used for iterating through the key/value 
        ///       pairs contained in the collection.</para>
        /// </devdoc>
        public IEnumerator GetEnumerator() {
            return new HttpStaticObjectsEnumerator((IDictionaryEnumerator)_objects.GetEnumerator());
        }
 
 
        /// <devdoc>
        ///    <para>Copies members of the collection into an array.</para>
        /// </devdoc>
        public void CopyTo(Array array, int index) {
            for (IEnumerator e = this.GetEnumerator(); e.MoveNext();)
                array.SetValue(e.Current, index++);
        }
 
 
        /// <devdoc>
        ///    <para>Gets an object that can be used to synchronize access to the collection.</para>
        /// </devdoc>
        public Object SyncRoot {
            get { return this;}
        }
 
 
        /// <devdoc>
        ///    <para>Gets a value indicating whether the collection is read-only.</para>
        /// </devdoc>
        public bool IsReadOnly {
            get { return true;}
        }
 
 
        /// <devdoc>
        ///    <para>Gets a value indicating whether the collection is synchronized.</para>
        /// </devdoc>
        public bool IsSynchronized {
            get { return false;}
        }
 
 
        public void Serialize(BinaryWriter writer) {
            IDictionaryEnumerator   e;
            HttpStaticObjectsEntry  entry;
            bool                    hasInstance;
 
            writer.Write(Count);
 
            e = _objects.GetEnumerator();
            while (e.MoveNext()) {
                entry = (HttpStaticObjectsEntry)e.Value;
                writer.Write(entry.Name);
                hasInstance = entry.HasInstance;
                writer.Write(hasInstance);
 
                if (hasInstance) {
                    AltSerialization.WriteValueToStream(entry.Instance, writer);
                }
                else {
                    writer.Write(entry.ObjectType.FullName);
                    writer.Write(entry.LateBound);
                }
            }
        }
 
 
        static public HttpStaticObjectsCollection Deserialize(BinaryReader reader) {
            int     count;
            string  name;
            string  typename;
            bool    hasInstance;
            Object  instance;
            HttpStaticObjectsEntry  entry;
            HttpStaticObjectsCollection col;
 
            col = new HttpStaticObjectsCollection();
 
            count = reader.ReadInt32();
            while (count-- > 0) {
                name = reader.ReadString();
                hasInstance = reader.ReadBoolean();
                if (hasInstance) {
                    instance = AltSerialization.ReadValueFromStream(reader);
                    entry = new HttpStaticObjectsEntry(name, instance, 0);
                }
                else {
                    typename = reader.ReadString();
                    bool lateBound = reader.ReadBoolean();
                    entry = new HttpStaticObjectsEntry(name, Type.GetType(typename), lateBound);
                }
 
                col._objects.Add(name, entry);
            }
 
            return col;
        }
    }
 
//
// Dictionary entry class
//
 
    internal class HttpStaticObjectsEntry {
        private String _name;
        private Type   _type;
        private bool   _lateBound;
        private Object _instance;
 
        internal HttpStaticObjectsEntry(String name, Type t, bool lateBound) {
            _name = name;
            _type = t;
            _lateBound = lateBound;
            _instance = null;
        }
 
        internal HttpStaticObjectsEntry(String name, Object instance, int dummy) {
            _name = name;
            _type = instance.GetType();
            _instance = instance;
        }
 
        internal String Name {
            get { return _name;} 
        }
 
        internal Type ObjectType {
            get { return _type;} 
        }
 
        internal bool LateBound {
            get { return _lateBound;} 
        }
 
        internal Type DeclaredType {
            get { return _lateBound ? typeof(object) : ObjectType; }
        }
 
        internal bool HasInstance {
            get { return(_instance != null);}
        }
 
        internal Object Instance {
            get {
                if (_instance == null) {
                    lock (this) {
                        if (_instance == null)
                            _instance = Activator.CreateInstance(_type);
                    }
                }
 
                return _instance;
            }
        }
    }
 
    //
    // Enumerator class for static objects collection
    //
    internal class HttpStaticObjectsEnumerator : IDictionaryEnumerator {
        private IDictionaryEnumerator _enum;
 
        internal HttpStaticObjectsEnumerator(IDictionaryEnumerator e) {
            _enum = e;
        }
 
        // Dictionary enumarator implementation
 
        public void Reset() {
            _enum.Reset();
        }
 
        public bool MoveNext() {
            return _enum.MoveNext();
        }
 
        public Object Key {
            get {
                return _enum.Key;
            }
        }
 
        public Object Value {
            get {
                HttpStaticObjectsEntry e = (HttpStaticObjectsEntry)_enum.Value;
 
                if (e == null)
                    return null;
 
                return e.Instance;
            }
        }
 
        public Object Current {
            get {
                return Entry;
            }
        }
 
        public DictionaryEntry Entry {
            get {
                return new DictionaryEntry(_enum.Key, this.Value);
            }
        }
    }
 
}