InheritanceService.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / CompMod / System / ComponentModel / Design / InheritanceService.cs / 1 / InheritanceService.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
namespace System.ComponentModel.Design {
 
    using System;
    using System.Collections;
    using System.ComponentModel;
    using Microsoft.Win32; 
    using System.Diagnostics;
    using System.Reflection; 
    using System.Windows.Forms; 
    using System.ComponentModel.Design.Serialization;
    using AccessedThroughPropertyAttribute = System.Runtime.CompilerServices.AccessedThroughPropertyAttribute; 
    using System.Globalization;

    /// 
    ///  
    ///     Provides a set of methods
    ///       for analyzing and identifying inherited components. 
    ///  
    public class InheritanceService : IInheritanceService, IDisposable {
 
        private static TraceSwitch InheritanceServiceSwitch = new TraceSwitch("InheritanceService", "InheritanceService : Debug inheritance scan.");

        private Hashtable inheritedComponents;
 
        // While we're adding an inherited component, we must be wary of components
        // that the inherited component adds as a result of being sited.  These 
        // are treated as inherited as well.  To track these, we keep track of the 
        // component we're currently adding as well as it's inheritance attribute.
        // During the add, we sync IComponentAdding events and push in the component 
        //
        private IComponent addingComponent;
        private InheritanceAttribute addingAttribute;
 
        /// 
        ///  
        ///     
        ///       Initializes a new instance of the  class.
        ///     
        /// 
        public InheritanceService() {
            inheritedComponents = new Hashtable();
        } 

        ///  
        ///  
        ///    Disposes of the resources (other than memory) used by
        ///       the . 
        /// 
        public void Dispose() {
            Dispose(true);
        } 

        protected virtual void Dispose(bool disposing) { 
            if (disposing && inheritedComponents != null) { 
                inheritedComponents.Clear();
                inheritedComponents = null; 
            }
        }

        ///  
        /// 
        /// Adds inherited components to the . 
        ///  
        public void AddInheritedComponents(IComponent component, IContainer container) {
            AddInheritedComponents(component.GetType(), component, container); 
        }

        /// 
        ///  
        /// Adds inherited components to the .
        ///  
        protected virtual void AddInheritedComponents(Type type, IComponent component, IContainer container) { 

            // We get out now if this component type is not assignable from IComponent.  We only walk 
            // down to the component level.
            //
            if (type == null || !typeof(IComponent).IsAssignableFrom(type)) {
                return; 
            }
 
            Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "Searching for inherited components on '" + type.FullName + "'."); 

            Debug.Indent(); 

            ISite site = component.Site;
            IComponentChangeService cs = null;
            INameCreationService ncs = null; 

            if (site != null) { 
                ncs = (INameCreationService)site.GetService(typeof(INameCreationService)); 

                cs = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); 
                if (cs != null) {
                    cs.ComponentAdding += new ComponentEventHandler(this.OnComponentAdding);
                }
            } 

            try { 
                while(type != typeof(object)) { 

                    Type reflect = TypeDescriptor.GetReflectionType(type); 

                    FieldInfo[] fields = reflect.GetFields(BindingFlags.Instance |
                                                        BindingFlags.DeclaredOnly |
                                                        BindingFlags.Public | 
                                                        BindingFlags.NonPublic);
 
                    Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "...found " + fields.Length.ToString(CultureInfo.InvariantCulture) + " fields."); 

                    for (int i = 0; i < fields.Length; i++) { 

                        FieldInfo field = fields[i];
                        string name = field.Name;
 
                        // Get out now if this field is not assignable from IComponent.
                        // 
                        if (!typeof(IComponent).IsAssignableFrom(field.FieldType)) { 
                            Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "...skipping " + name + ": Not IComponent");
                            continue; 
                        }

                        // Now check the attributes of the field and get out if it isn't something that can
                        // be inherited. 
                        //
                        Debug.Assert(!field.IsStatic, "Instance binding shouldn't have found this field"); 
 
                        // If the value of the field is null, then don't mess with it.  If it wasn't assigned
                        // when our base class was created then we can't really use it. 
                        //
                        Object value = field.GetValue(component);
                        if (value == null) {
                            Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "...skipping " + name + ": Contains NULL"); 
                            continue;
                        } 
 
                        // We've been fine up to this point looking at the field.  Now, however, we must check to see
                        // if this field has an AccessedThroughPropertyAttribute on it.  If it does, then 
                        // we must look for the property and use its name and visibility for the remainder of the
                        // scan.  Should any of this bail we just use the field.
                        //
                        MemberInfo member = field; 

                        object[] fieldAttrs = field.GetCustomAttributes(typeof(AccessedThroughPropertyAttribute), false); 
                        if (fieldAttrs != null && fieldAttrs.Length > 0) { 
                            Debug.Assert(fieldAttrs.Length == 1, "Non-inheritable attribute has more than one copy");
                            Debug.Assert(fieldAttrs[0] is AccessedThroughPropertyAttribute, "Reflection bug:  GetCustomAttributes(type) didn't discriminate by type"); 
                            AccessedThroughPropertyAttribute propAttr = (AccessedThroughPropertyAttribute)fieldAttrs[0];

                            PropertyInfo fieldProp = reflect.GetProperty(propAttr.PropertyName,
                                                                      BindingFlags.Instance | 
                                                                      BindingFlags.Public |
                                                                      BindingFlags.NonPublic); 
 
                            Debug.Assert(fieldProp != null, "Field declared with AccessedThroughPropertyAttribute has no associated property");
                            Debug.Assert(fieldProp.PropertyType == field.FieldType, "Field declared with AccessedThroughPropertyAttribute is associated with a property with a different return type."); 
                            if (fieldProp != null && fieldProp.PropertyType == field.FieldType) {

                                // If the property cannot be read, it is useless to us.
                                // 
                                if (!fieldProp.CanRead) {
                                    continue; 
                                } 

                                // We never access the set for the property, so we 
                                // can concentrate on just the get method.
                                member = fieldProp.GetGetMethod(true);
                                Debug.Assert(member != null, "GetGetMethod for property didn't return a method, but CanRead is true");
                                name = propAttr.PropertyName; 
                            }
                        } 
 
                        // Add a user hook to add or remove members.  The default hook here ignores all inherited
                        // private members. 
                        //
                        bool ignoreMember = IgnoreInheritedMember(member, component);

                        // We now have an inherited member.  Gather some information about it and then 
                        // add it to our list.  We must always add to our list, but we may not want to
                        // add it to the container.  That is up to the IngoreInheritedMember method. 
                        // We add here because there are components in the world that, when sited, 
                        // add their children to the container too. That's fine, but we want to make sure
                        // we account for them in the inheritance service too. 
                        //
                        Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "...found inherited member '" + name + "'");
                        Debug.Indent();
                        Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "Type: " + field.FieldType.FullName); 

                        InheritanceAttribute attr; 
 
                        Debug.Assert(value is IComponent, "Value of inherited field is not IComponent.  How did this value get into the datatype?");
 
                        bool privateInherited = false;

                        if (ignoreMember) {
                            // If we are ignoring this member, then always mark it as private. 
                            // The designer doesn't want it; we only do this in case some other
                            // component adds this guy to the container. 
                            // 
                            privateInherited = true;
                        } 
                        else {
                            if (member is FieldInfo) {
                                FieldInfo fi = (FieldInfo)member;
                                privateInherited = fi.IsPrivate | fi.IsAssembly; 
                            }
                            else if (member is MethodInfo) { 
                                MethodInfo mi = (MethodInfo)member; 
                                privateInherited = mi.IsPrivate | mi.IsAssembly;
                            } 
                        }

                        if (privateInherited) {
                            attr = InheritanceAttribute.InheritedReadOnly; 
                            Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "Inheritance: Private");
                        } 
                        else { 
                            Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "Inheritance: Public");
                            attr = InheritanceAttribute.Inherited; 
                        }

                        bool notPresent = (inheritedComponents[value] == null);
                        inheritedComponents[value] = attr; 

                        if (!ignoreMember && notPresent) { 
                            Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "Adding " + name + " to container."); 
                            try {
                                addingComponent = (IComponent)value; 
                                addingAttribute = attr;

                                // Lets make sure this is a valid name
                                if (ncs == null || ncs.IsValidName(name)) { 
                                    try {
                                        container.Add((IComponent)value, name); 
                                    } 
                                    catch { // We do not always control the base components,
                                        // and there could be a lot of rogue base 
                                        // components. If there are exceptions when adding
                                        // them, lets just ignore and continue.
                                    }
                                } 
                            }
                            finally { 
                                addingComponent = null; 
                                addingAttribute = null;
                            } 
                        }
                        Debug.Unindent();
                    }
 
                    type = type.BaseType;
                } 
            } 
            finally {
                if (cs != null) { 
                    cs.ComponentAdding -= new ComponentEventHandler(this.OnComponentAdding);
                }

                Debug.Unindent(); 
            }
        } 
 
        /// 
        ///  
        ///    Indicates the inherited members to ignore.
        /// 
        protected virtual bool IgnoreInheritedMember(MemberInfo member, IComponent component) {
 
            // Our default implementation ignores all private or assembly members.
            // 
            if (member is FieldInfo) { 
                FieldInfo field = (FieldInfo)member;
                return field.IsPrivate || field.IsAssembly; 
            }
            else if (member is MethodInfo) {
                MethodInfo method = (MethodInfo)member;
                return method.IsPrivate || method.IsAssembly; 
            }
 
            Debug.Fail("Unknown member type passed to IgnoreInheritedMember"); 
            return true;
        } 

        /// 
        /// 
        ///    Gets the inheritance attribute 
        ///       of the specified component.
        ///  
        public InheritanceAttribute GetInheritanceAttribute(IComponent component) { 
            InheritanceAttribute attr = (InheritanceAttribute)inheritedComponents[component];
            if (attr == null) { 
                attr = InheritanceAttribute.Default;
            }

            return attr; 
        }
 
        private void OnComponentAdding(object sender, ComponentEventArgs ce) { 
            if (addingComponent != null && addingComponent != ce.Component) {
                Debug.WriteLineIf(InheritanceServiceSwitch.TraceVerbose, "Adding component... " + ce.Component.ToString() ); 

                inheritedComponents[ce.Component] = InheritanceAttribute.InheritedReadOnly;

                // If this component is being added to a nested container of addingComponent, it should 
                // get the same inheritance level.
                INestedContainer nested = sender as INestedContainer; 
                if (nested != null && nested.Owner == addingComponent) { 
                    inheritedComponents[ce.Component] = addingAttribute;
                } 
            }
        }
    }
} 


// 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