Code:
/ FX-1434 / FX-1434 / 1.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; ////// /// 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; ///Provides a set of methods /// for analyzing and identifying inherited components. ////// /// public InheritanceService() { inheritedComponents = new Hashtable(); } ////// Initializes a new instance of the ///class. /// /// /// public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing && inheritedComponents != null) { inheritedComponents.Clear(); inheritedComponents = null; } } ///Disposes of the resources (other than memory) used by /// 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(); } } ///Adds inherited components to the ///. /// /// 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; } ///Indicates the inherited members to ignore. ////// /// 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.Gets the inheritance attribute /// of the specified component. ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CodeConstructor.cs
- TargetControlTypeAttribute.cs
- DBAsyncResult.cs
- CustomErrorCollection.cs
- FrugalList.cs
- InternalEnumValidatorAttribute.cs
- DocumentStream.cs
- TemplateControlCodeDomTreeGenerator.cs
- TableLayoutCellPaintEventArgs.cs
- EventRecord.cs
- StringUtil.cs
- XmlJsonReader.cs
- UniqueSet.cs
- FontUnitConverter.cs
- BamlLocalizabilityResolver.cs
- ComContractElement.cs
- ListViewHitTestInfo.cs
- StrokeFIndices.cs
- SimpleType.cs
- TextContainerHelper.cs
- GPPOINT.cs
- CommandManager.cs
- QilGeneratorEnv.cs
- BaseCodeDomTreeGenerator.cs
- XmlReaderSettings.cs
- PersonalizationStateInfoCollection.cs
- ExtensibleClassFactory.cs
- Rules.cs
- JsonEnumDataContract.cs
- SqlFacetAttribute.cs
- XamlDesignerSerializationManager.cs
- WebServiceData.cs
- TextTreeText.cs
- WeakReferenceEnumerator.cs
- ReferenceConverter.cs
- ExtendedProperty.cs
- ButtonBaseAutomationPeer.cs
- PrintDocument.cs
- WebCodeGenerator.cs
- ConfigUtil.cs
- UrlAuthFailedErrorFormatter.cs
- FontFamilyIdentifier.cs
- RoutedEventHandlerInfo.cs
- PointCollection.cs
- RawStylusActions.cs
- BitmapFrame.cs
- MonitoringDescriptionAttribute.cs
- ImageIndexConverter.cs
- LocalizableResourceBuilder.cs
- DataControlImageButton.cs
- sqlstateclientmanager.cs
- EventPrivateKey.cs
- Style.cs
- SQLString.cs
- UInt16Storage.cs
- SapiAttributeParser.cs
- BevelBitmapEffect.cs
- TableDetailsCollection.cs
- DataServiceExpressionVisitor.cs
- FilteredAttributeCollection.cs
- BigIntegerStorage.cs
- StrongNameUtility.cs
- CodeAttributeArgumentCollection.cs
- CodeCommentStatement.cs
- NameValuePermission.cs
- TrackPointCollection.cs
- BlockingCollection.cs
- ReturnType.cs
- EncoderNLS.cs
- RotateTransform3D.cs
- ResolvedKeyFrameEntry.cs
- MatrixTransform.cs
- BezierSegment.cs
- DateTimeStorage.cs
- DataGridColumnEventArgs.cs
- IntellisenseTextBox.designer.cs
- ImageIndexEditor.cs
- SizeF.cs
- Converter.cs
- TraceContextRecord.cs
- DetailsViewAutoFormat.cs
- ProcessThread.cs
- RuntimeCompatibilityAttribute.cs
- HeaderCollection.cs
- FlowLayout.cs
- ScriptDescriptor.cs
- DynamicRouteExpression.cs
- SqlDataSourceSelectingEventArgs.cs
- _NegoStream.cs
- EntityConnectionStringBuilder.cs
- DocumentViewerConstants.cs
- ActivationArguments.cs
- ComplexTypeEmitter.cs
- InkCollectionBehavior.cs
- DataGridViewCellEventArgs.cs
- PropertyChangedEventArgs.cs
- ToolStripSeparatorRenderEventArgs.cs
- SQLInt32.cs
- Lasso.cs
- MimeReflector.cs