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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlSchemaSimpleTypeRestriction.cs
- XmlChildEnumerator.cs
- ReflectTypeDescriptionProvider.cs
- Expr.cs
- AmbientLight.cs
- SimpleMailWebEventProvider.cs
- RunClient.cs
- LZCodec.cs
- RequestCacheManager.cs
- DataServiceContext.cs
- ResetableIterator.cs
- ProtocolsSection.cs
- ControlBuilderAttribute.cs
- ObjectDataSourceSelectingEventArgs.cs
- SerialErrors.cs
- CodeValidator.cs
- UpdateCommand.cs
- AlphaSortedEnumConverter.cs
- StorageMappingItemLoader.cs
- MenuItemStyle.cs
- EventLogPermissionEntry.cs
- PasswordBox.cs
- BaseCodePageEncoding.cs
- SslStream.cs
- ContainerFilterService.cs
- WindowsStartMenu.cs
- ReachDocumentReferenceCollectionSerializer.cs
- DrawingContextDrawingContextWalker.cs
- FixedDocument.cs
- ArraySet.cs
- SchemaNames.cs
- GetMemberBinder.cs
- StrokeNodeData.cs
- SystemWebSectionGroup.cs
- KeysConverter.cs
- CommonXSendMessage.cs
- RawStylusSystemGestureInputReport.cs
- ActivityInstanceMap.cs
- RSAOAEPKeyExchangeFormatter.cs
- CodeObject.cs
- DataRowView.cs
- _SafeNetHandles.cs
- CodeSnippetStatement.cs
- SelfIssuedAuthRSAPKCS1SignatureDeformatter.cs
- DelegateBodyWriter.cs
- FixUpCollection.cs
- ExtentKey.cs
- SHA1CryptoServiceProvider.cs
- ObjectQuery_EntitySqlExtensions.cs
- OrderedHashRepartitionStream.cs
- LinqToSqlWrapper.cs
- Native.cs
- MissingManifestResourceException.cs
- ItemCheckedEvent.cs
- ParallelTimeline.cs
- AssemblyUtil.cs
- CalculatedColumn.cs
- ResourceContainer.cs
- SharedDp.cs
- FontStretchConverter.cs
- DiscoveryClientReferences.cs
- ConfigurationSectionCollection.cs
- _ConnectionGroup.cs
- VisualProxy.cs
- RadioButtonBaseAdapter.cs
- ParameterCollection.cs
- CurrentChangedEventManager.cs
- CodeCastExpression.cs
- WSHttpBinding.cs
- GridSplitter.cs
- HierarchicalDataSourceDesigner.cs
- WebServicesSection.cs
- ProfileEventArgs.cs
- RNGCryptoServiceProvider.cs
- UserNameSecurityTokenProvider.cs
- RuntimeHelpers.cs
- PropertyPathWorker.cs
- DirectoryInfo.cs
- StyleSelector.cs
- UpDownBaseDesigner.cs
- ProtectedConfiguration.cs
- DelegatingTypeDescriptionProvider.cs
- EndpointAddressProcessor.cs
- RadialGradientBrush.cs
- GeometryCombineModeValidation.cs
- Hashtable.cs
- Stack.cs
- ExpressionBuilder.cs
- Expression.cs
- XmlException.cs
- IDispatchConstantAttribute.cs
- XhtmlCssHandler.cs
- PropertyEmitterBase.cs
- ProcessHost.cs
- ExpandSegment.cs
- SecurityKeyUsage.cs
- WebServiceHostFactory.cs
- EndPoint.cs
- ExtendedTransformFactory.cs
- ResXBuildProvider.cs