ComponentCache.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / CompMod / System / ComponentModel / Design / Serialization / ComponentCache.cs / 1 / ComponentCache.cs

                            namespace System.ComponentModel.Design.Serialization 
{
    using System;
    using System.Configuration;
    using System.Diagnostics; 
    using System.Design;
    using System.CodeDom; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.ComponentModel; 
    using System.Windows.Forms;
    using System.Globalization;

 

    ///  
    ///  
    ///  This class is used to cache serialized properties and events of components to speed-up Design to Code view switches
    ///  
    internal class ComponentCache : IDisposable
    {
        private Dictionary cache;
        private IDesignerSerializationManager serManager; 
        private bool enabled = true;
 
 
        internal ComponentCache(IDesignerSerializationManager manager){
            serManager = manager; 
            IComponentChangeService cs = (IComponentChangeService)manager.GetService(typeof(IComponentChangeService));
            if (cs != null){
                cs.ComponentChanging  += new ComponentChangingEventHandler(this.OnComponentChanging);
                cs.ComponentChanged   += new ComponentChangedEventHandler(this.OnComponentChanged); 
                cs.ComponentRemoving  += new ComponentEventHandler(this.OnComponentRemove);
                cs.ComponentRemoved   += new ComponentEventHandler(this.OnComponentRemove); 
                cs.ComponentRename    += new ComponentRenameEventHandler(this.OnComponentRename); 
            }
 
            DesignerOptionService options = manager.GetService(typeof(DesignerOptionService)) as DesignerOptionService;

            object optionValue = null;
            if (options != null) { 
                PropertyDescriptor componentCacheProp = options.Options.Properties["UseOptimizedCodeGeneration"];
                if (componentCacheProp != null) { 
                    optionValue = componentCacheProp.GetValue(null); 
                }
 
                if (optionValue != null && optionValue is bool) {
                    enabled = (bool) optionValue;
                }
            } 
        }
 
        internal bool Enabled { 
            get {
                return enabled; 
            }
        }

 

        ///  
        ///  
        ///     Access serialized Properties and events for the given component
        ///  
        internal Entry this[object component]
        {
            get {
 
                if (component == null)
                { 
                    throw new ArgumentNullException("component"); 
                }
 
                Entry result;

                if (cache != null && cache.TryGetValue(component, out result)) {
                    if (result != null && result.Valid && Enabled) { 
                        return result;
                    } 
                } 
                return null;
            } 
            set {
                if (cache == null && Enabled) {
                    cache = new Dictionary();
                } 
                // it's a 1:1 relationship so we can go back from entry to
                // component (if it's not setup yet.. which should not happen, see ComponentCodeDomSerializer.cs::Serialize for more info) 
 
                if (cache != null && component is IComponent) {
                    if(value != null && value.Component == null) { 
                        value.Component = component;
                    }
                    cache[component] = value;
                } 
            }
        } 
 
        internal Entry GetEntryAll(object component) {
            Entry result = null; 
            if (cache != null && cache.TryGetValue(component, out result)) {
                return result;
            }
 
            return null;
        } 
 
        internal bool ContainsLocalName(string name) {
            if (cache == null) { 
                return false;
            }

            foreach(KeyValuePair kvp in cache) { 
                List localNames = kvp.Value.LocalNames;
                if (localNames != null && localNames.Contains(name)) { 
                    return true; 
                }
            } 

            return false;
        }
 
        public void Dispose()
        { 
            if (serManager != null) { 
                IComponentChangeService cs = (IComponentChangeService)serManager.GetService(typeof(IComponentChangeService));
 
                if (cs != null)
                {
                    cs.ComponentChanging  -= new ComponentChangingEventHandler(this.OnComponentChanging);
                    cs.ComponentChanged   -= new ComponentChangedEventHandler(this.OnComponentChanged); 
                    cs.ComponentRemoving  -= new ComponentEventHandler(this.OnComponentRemove);
                    cs.ComponentRemoved   -= new ComponentEventHandler(this.OnComponentRemove); 
                    cs.ComponentRename    -= new ComponentRenameEventHandler(this.OnComponentRename); 
                }
            } 
        }

        private void OnComponentRename(object source, ComponentRenameEventArgs args) {
            // we might have a symbolic rename that has side effects beyond our control, 
            // so we don't have a choice but to clear the whole cache when a component gets renamed...
            if(cache!= null) { 
                cache.Clear(); 
            }
        } 

        private void OnComponentChanging(object source, ComponentChangingEventArgs ce) {
            if (cache != null) {
                if (ce.Component != null) { 
                    RemoveEntry(ce.Component);
 
                    if (!(ce.Component is IComponent) && serManager != null) { 
                        IReferenceService rs = serManager.GetService(typeof(IReferenceService)) as IReferenceService;
                        if (rs != null) { 
                            IComponent owningComp = rs.GetComponent(ce.Component);
                            if (owningComp != null) {
                                RemoveEntry(owningComp);
                            } 
                            else {
                                // Hmm. We were notified about an object change, but were unable to relate it 
                                // back to a component we know about. In this situation, we have no option 
                                // but to clear the whole cache, since we don't want serialization to miss
                                // something. See VSWhidbey #404813 for an example of what we would have missed. 
                                cache.Clear();
                            }
                        }
                    } 
                }
                else { 
                    cache.Clear(); 
                }
            } 
        }

        private void OnComponentChanged(object source, ComponentChangedEventArgs ce) {
            if (cache != null) { 
                if (ce.Component != null) {
                    RemoveEntry(ce.Component); 
 
                    if (!(ce.Component is IComponent) && serManager != null) {
                        IReferenceService rs = serManager.GetService(typeof(IReferenceService)) as IReferenceService; 
                        if (rs != null) {
                            IComponent owningComp = rs.GetComponent(ce.Component);
                            if (owningComp != null) {
                                RemoveEntry(owningComp); 
                            }
                            else { 
                                // Hmm. We were notified about an object change, but were unable to relate it 
                                // back to a component we know about. In this situation, we have no option
                                // but to clear the whole cache, since we don't want serialization to miss 
                                // something. See VSWhidbey #404813 for an example of what we would have missed.
                                cache.Clear();
                            }
                        } 
                    }
                } 
                else { 
                    cache.Clear();
                } 
            }
        }

        private void OnComponentRemove(object source, ComponentEventArgs ce) { 
           if (cache != null) {
               if (ce.Component != null && !(ce.Component is IExtenderProvider)) { 
                   RemoveEntry(ce.Component); 
               }
               else { 
                   cache.Clear();
               }
            }
        } 

        ///  
        ///     Helper to remove an entry from the cache. 
        /// 
        internal void RemoveEntry(object component) { 
                Entry entry = null;

                if (cache != null && cache.TryGetValue(component, out entry)) {
                    if (entry.Tracking) { 
                        cache.Clear();
                        return; 
                    } 

                    cache.Remove(component); 

                    // Clear its dependencies, if any
                    if (entry.Dependencies != null) {
                        foreach(object parent in entry.Dependencies) { 
                            RemoveEntry(parent);
                        } 
                    } 

                } 
        }

        internal struct ResourceEntry {
            public bool ForceInvariant; 
            public bool EnsureInvariant;
            public bool ShouldSerializeValue; 
            public string Name; 
            public object Value;
            public PropertyDescriptor PropertyDescriptor; 
            public ExpressionContext ExpressionContext;
        }

        // A single cache entry 
        internal sealed class Entry {
            private ComponentCache cache; 
            private List dependencies; 
            private List localNames;
            private List resources; 
            private List metadata;
            private bool valid;
            private bool tracking;
 
            internal Entry(ComponentCache cache) {
                this.cache = cache; 
                valid = true; 
            }
 
            public object Component; // pointer back to the component that generated this entry
            public CodeStatementCollection Statements;

            public ICollection Metadata { 
                get {
                    return metadata; 
                } 
            }
 
            public ICollection Resources {
                get {
                    return resources;
                } 
            }
 
            public List Dependencies { 
                get {
                    return dependencies; 
                }
            }

            internal List LocalNames { 
                get {
                    return localNames; 
                } 
            }
 
            internal bool Valid {
                get {
                    return valid;
                } 
                set {
                    valid = value; 
                } 
            }
 
            internal bool Tracking {
                get {
                    return tracking;
                } 
                set {
                    tracking = value; 
                } 
            }
 		 
            internal void AddLocalName(string name) {
                if (localNames == null) {
                    localNames = new List();
                } 

                localNames.Add(name); 
            } 

            public void AddDependency(object dep) { 
                if(dependencies == null) {
                    dependencies = new List();
                }
 
                if (!dependencies.Contains(dep)) {
                    dependencies.Add(dep); 
                } 
            }
 
            public void AddMetadata(ResourceEntry re) {
                if (metadata == null) {
                    metadata = new List();
                } 
                metadata.Add(re);
            } 
 
            public void AddResource(ResourceEntry re) {
                if (resources == null) { 
                    resources = new List();
                }
                resources.Add(re);
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK