public void Find () { EventDescriptor descA = new MockEventDescriptor ("hehe_\u0061\u030a", null); EventDescriptor descB = new MockEventDescriptor ("heh_\u00e5", null); EventDescriptor descC = new MockEventDescriptor ("Foo", null); EventDescriptor descD = new MockEventDescriptor ("FOo", null); EventDescriptor descE = new MockEventDescriptor ("Aim", null); EventDescriptor descF = new MockEventDescriptor ("Bar", null); EventDescriptorCollection col = new EventDescriptorCollection ( new EventDescriptor [] { descA, descB, descC, descD, descE, descF }); #if NET_2_0 Assert.IsNull (col.Find ("heh_\u0061\u030a", false), "#1"); Assert.IsNull (col.Find ("hehe_\u00e5", false), "#2"); #else Assert.AreSame (descB, col.Find ("heh_\u0061\u030a", false), "#1"); Assert.AreSame (descA, col.Find ("hehe_\u00e5", false), "#2"); #endif Assert.AreSame (descA, col.Find ("hehe_\u0061\u030a", false), "#3"); Assert.AreSame (descB, col.Find ("heh_\u00e5", false), "#4"); Assert.IsNull (col.Find ("foo", false), "#5"); Assert.AreSame (descC, col.Find ("foo", true), "#6"); Assert.AreSame (descD, col.Find ("FOo", false), "#7"); Assert.AreSame (descC, col.Find ("FOo", true), "#8"); Assert.IsNull (col.Find ("fOo", false), "#9"); Assert.AreSame (descC, col.Find ("fOo", true), "#10"); Assert.IsNull (col.Find ("AIm", false), "#11"); Assert.AreSame (descE, col.Find ("AIm", true), "#12"); Assert.IsNull (col.Find ("AiM", false), "#13"); Assert.AreSame (descE, col.Find ("AiM", true), "#14"); Assert.AreSame (descE, col.Find ("Aim", false), "#15"); Assert.AreSame (descE, col.Find ("Aim", true), "#16"); }
public ClassInstance(Type wrappedType, Type objectInstanceType) { _wrappedType = wrappedType; // Create a wrapper for each non-collection property. _classProperties = _wrappedType .GetProperties() .Select(p => ClassMemberIndependent.Intercept(new ClassMemberProperty(p, objectInstanceType))) .Concat<ClassMember>(_wrappedType .GetFields() .Select(f => ClassMemberIndependent.Intercept(new ClassMemberField(f, objectInstanceType)))) .ToList(); _classProperties.AddRange( (from method in _wrappedType.GetMethods() where method.ReturnType == typeof(void) && method.GetParameters().Length == 0 let can = (from p in _classProperties where p.Name == "Can" + method.Name && p.PropertyType == typeof(bool) select p).FirstOrDefault() select new ClassMemberCommand(method, can, objectInstanceType)).ToList()); _propertyDescriptors = new PropertyDescriptorCollection(_classProperties.ToArray()); // Create a pass-through for each event. _classEvents = _wrappedType .GetEvents() .Select(e => new ClassEvent(e)) .ToList(); _eventDescriptors = new EventDescriptorCollection(_classEvents.ToArray()); }
public ProxyTypeDescriptor(Type type) { Meta = TypeMeta.Get(type); ProxyType = typeof(PlatformProxy<>).MakeGenericType(type); _properties = Meta.Members.Select(m => new ProxyPropertyDescriptor(this, m)).ToArray(); _propertyCollection = new PropertyDescriptorCollection(_properties); _events = new EventDescriptorCollection(type.GetEvents().Select(e => new ProxyEventDescriptor(e)).ToArray()); }
public void Find_Key_Null () { EventDescriptorCollection descriptors = new EventDescriptorCollection ( new EventDescriptor[] { new MockEventDescriptor ("A", "X"), new MockEventDescriptor ("b", "Y")}); Assert.IsNull (descriptors.Find (null, false), "#1"); Assert.IsNull (descriptors.Find (null, true), "#2"); }
public System.ComponentModel.PropertyDescriptorCollection GetEventProperties(System.ComponentModel.EventDescriptorCollection events) { ArrayList props = new ArrayList(); foreach (EventDescriptor e in events) { props.Add(GetEventProperty(e)); } return(new PropertyDescriptorCollection((PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor)))); }
PropertyDescriptorCollection IEventBindingService.GetEventProperties(EventDescriptorCollection events) { if (events == null) { throw new ArgumentNullException("events"); } List<PropertyDescriptor> list = new List<PropertyDescriptor>(events.Count); for (int i = 0; i < events.Count; i++) { if (!this.HasGenericArgument(events[i])) { PropertyDescriptor item = new EventPropertyDescriptor(events[i], this); list.Add(item); } } return new PropertyDescriptorCollection(list.ToArray()); }
PropertyDescriptorCollection IEventBindingService.GetEventProperties(EventDescriptorCollection events) { if (events == null) { throw new ArgumentNullException("events"); } PropertyDescriptor[] props = new PropertyDescriptor[events.Count]; if (this._eventProperties == null) { this._eventProperties = new Hashtable(); } for (int i = 0; i < events.Count; i++) { object eventHashCode = this.GetEventDescriptorHashCode(events[i]); props[i] = (PropertyDescriptor) this._eventProperties[eventHashCode]; if (props[i] == null) { props[i] = new EventPropertyDescriptor(events[i], this); this._eventProperties[eventHashCode] = props[i]; } } return new PropertyDescriptorCollection(props); }
public override EventDescriptorCollection GetEvents() { if (_events != null) { return(_events); } bool cache = true; EventInfo[] events = _component.GetType().GetEvents(); Hashtable t = new Hashtable(); foreach (EventInfo ev in events) { t [ev.Name] = new ReflectionEventDescriptor(ev); } if (_component.Site != null) { ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService)_component.Site.GetService(typeof(ITypeDescriptorFilterService)); if (filter != null) { cache = filter.FilterEvents(_component, t); } } ArrayList atts = new ArrayList(); atts.AddRange(t.Values); EventDescriptorCollection attCol = new EventDescriptorCollection(atts); if (cache) { _events = attCol; } return(attCol); }
public EventDescriptor GetDefaultEvent() { if (_gotDefaultEvent) { return(_defaultEvent); } DefaultEventAttribute attr = (DefaultEventAttribute)GetAttributes()[typeof(DefaultEventAttribute)]; if (attr == null || attr.Name == null) { _defaultEvent = null; } else { EventDescriptorCollection events = GetEvents(); _defaultEvent = events [attr.Name]; #if !NET_2_0 // In our test case (TypeDescriptorTest.TestGetDefaultEvent), we have // a scenario where a custom filter adds the DefaultEventAttribute, // but its FilterEvents method removes the event the // DefaultEventAttribute applied to. .NET 1.x accepts this and returns // the *other* event defined in the class. // // Consequently, we know we have a DefaultEvent, but we need to check // and ensure that the requested event is unfiltered. If it is, just // grab the first element in the collection. if (_defaultEvent == null && events.Count > 0) { _defaultEvent = events [0]; } #endif } _gotDefaultEvent = true; return(_defaultEvent); }
/// <devdoc> /// Metadata merging is the second stage of our metadata pipeline. This stage /// merges extended metdata with primary metadata, and stores it in /// the cache if it is available. /// </devdoc> private static ICollection PipelineMerge(int pipelineType, ICollection primary, ICollection secondary, object instance, IDictionary cache) { // If there is no secondary collection, there is nothing to merge. // if (secondary == null || secondary.Count == 0) { return primary; } // Next, if we were given a cache, see if it has accurate data. // if (cache != null) { ICollection mergeCache = cache[_pipelineMergeKeys[pipelineType]] as ICollection; if (mergeCache != null && mergeCache.Count == (primary.Count + secondary.Count)) { // Walk the merge cache. IEnumerator mergeEnum = mergeCache.GetEnumerator(); IEnumerator primaryEnum = primary.GetEnumerator(); bool match = true; while(primaryEnum.MoveNext() && mergeEnum.MoveNext()) { if (primaryEnum.Current != mergeEnum.Current) { match = false; break; } } if (match) { IEnumerator secondaryEnum = secondary.GetEnumerator(); while(secondaryEnum.MoveNext() && mergeEnum.MoveNext()) { if (secondaryEnum.Current != mergeEnum.Current) { match = false; break; } } } if (match) { return mergeCache; } } } // Our cache didn't match. We need to merge metadata and return // the merged copy. We create an array list here, rather than // an array, because we want successive sections of the // pipeline to be able to modify it. // ArrayList list = new ArrayList(primary.Count + secondary.Count); foreach(object obj in primary) { list.Add(obj); } foreach(object obj in secondary) { list.Add(obj); } if (cache != null) { ICollection cacheValue; switch(pipelineType) { case PIPELINE_ATTRIBUTES: Attribute[] attrArray = new Attribute[list.Count]; list.CopyTo(attrArray, 0); cacheValue = new AttributeCollection(attrArray); break; case PIPELINE_PROPERTIES: PropertyDescriptor[] propArray = new PropertyDescriptor[list.Count]; list.CopyTo(propArray, 0); cacheValue = new PropertyDescriptorCollection(propArray, true); break; case PIPELINE_EVENTS: EventDescriptor[] eventArray = new EventDescriptor[list.Count]; list.CopyTo(eventArray, 0); cacheValue = new EventDescriptorCollection(eventArray, true); break; default: Debug.Fail("unknown pipeline type"); cacheValue = null; break; } Trace("Pipeline : Merge results being cached for {0}", instance.GetType().Name); cache[_pipelineMergeKeys[pipelineType]] = cacheValue; cache.Remove(_pipelineFilterKeys[pipelineType]); cache.Remove(_pipelineAttributeFilterKeys[pipelineType]); } return list; }
/// <devdoc> /// Refreshes the contents of this type descriptor. This does not /// actually requery, but it will clear our state so the next /// query re-populates. /// </devdoc> internal void Refresh() { _attributes = null; _events = null; _properties = null; _converter = null; _editors = null; _editorTypes = null; _editorCount = 0; }
public override EventDescriptorCollection GetEvents () { if (_events != null) return _events; EventInfo[] events = InfoType.GetEvents (); EventDescriptor[] descs = new EventDescriptor [events.Length]; for (int n=0; n<events.Length; n++) descs [n] = new ReflectionEventDescriptor (events[n]); _events = new EventDescriptorCollection (descs); return _events; }
private EventDescriptorCollection FilterEvents(EventDescriptorCollection origEvents) { // Create an enumerator containing only the events that are not in the provided list of event names // and fill an array with those selected events IEnumerable<EventDescriptor> selectedEvents = origEvents.OfType<EventDescriptor>().Where(e => _excludeBrowsableEvents.Contains(e.Name)); //IEnumerable<EventDescriptor> selectedEvents = origEvents.OfType<EventDescriptor>().Where(e => !_excludeBrowsableEvents.Contains(e.Name)); EventDescriptor[] descriptors = selectedEvents.ToArray(); // Return an EventDescriptorCollection containing only the filtered descriptors EventDescriptorCollection newCollection = new EventDescriptorCollection(descriptors); return newCollection; }
private EventDescriptorCollection(EventDescriptorCollection copyFrom, String[] names, IComparer comparer) { list = (ArrayList)(copyFrom.list.Clone()); InternalSort(names, comparer); }
PropertyDescriptorCollection IEventBindingService.GetEventProperties (EventDescriptorCollection events) { if (events == null) throw new ArgumentNullException ("events"); List<PropertyDescriptor> properties = new List <PropertyDescriptor>(); foreach (EventDescriptor eventDescriptor in events) properties.Add (((IEventBindingService)this).GetEventProperty (eventDescriptor)); return new PropertyDescriptorCollection (properties.ToArray ()); }
public static EventDescriptorCollection GetEvents(object component, Attribute[] attributes, bool noCustomTypeDesc) { ICollection events; if (component == null) { return new EventDescriptorCollection(null, true); } ICustomTypeDescriptor descriptor = GetDescriptor(component, noCustomTypeDesc); if (component is ICustomTypeDescriptor) { events = descriptor.GetEvents(attributes); if (noCustomTypeDesc) { ICustomTypeDescriptor extendedDescriptor = GetExtendedDescriptor(component); if (extendedDescriptor != null) { ICollection secondary = extendedDescriptor.GetEvents(attributes); events = PipelineMerge(2, events, secondary, component, null); } } else { events = PipelineFilter(2, events, component, null); events = PipelineAttributeFilter(2, events, attributes, component, null); } } else { IDictionary cache = GetCache(component); events = descriptor.GetEvents(attributes); events = PipelineInitialize(2, events, cache); ICustomTypeDescriptor descriptor3 = GetExtendedDescriptor(component); if (descriptor3 != null) { ICollection is4 = descriptor3.GetEvents(attributes); events = PipelineMerge(2, events, is4, component, cache); } events = PipelineFilter(2, events, component, cache); events = PipelineAttributeFilter(2, events, attributes, component, cache); } EventDescriptorCollection descriptors = events as EventDescriptorCollection; if (descriptors == null) { EventDescriptor[] array = new EventDescriptor[events.Count]; events.CopyTo(array, 0); descriptors = new EventDescriptorCollection(array, true); } return descriptors; }
public static EventDescriptorCollection GetEvents(Type componentType, Attribute[] attributes) { if (componentType == null) { return new EventDescriptorCollection(null, true); } EventDescriptorCollection events = GetDescriptor(componentType, "componentType").GetEvents(attributes); if ((attributes != null) && (attributes.Length > 0)) { ArrayList list = FilterMembers(events, attributes); if (list != null) { events = new EventDescriptorCollection((EventDescriptor[]) list.ToArray(typeof(EventDescriptor)), true); } } return events; }
[Test] // Sort (String [], IComparer) public void Sort4 () { EventDescriptorCollection descriptors; EventDescriptorCollection sorted; EventDescriptor descA = new MockEventDescriptor ("Foo", "B"); EventDescriptor descB = new MockEventDescriptor ("Aim", "C"); EventDescriptor descC = new MockEventDescriptor ("Bim", "A"); EventDescriptor descD = new MockEventDescriptor ("AIm", "E"); EventDescriptor descE = new MockEventDescriptor ("Boo", "D"); EventDescriptor descF = new MockEventDescriptor ("FOo", "F"); EventDescriptor [] props = new EventDescriptor [] { descA, descB, descC, descD, descE, descF }; descriptors = new EventDescriptorCollection (props); Assert.AreSame (descA, descriptors [0], "#A1"); Assert.AreSame (descB, descriptors [1], "#A2"); Assert.AreSame (descC, descriptors [2], "#A3"); Assert.AreSame (descD, descriptors [3], "#A4"); Assert.AreSame (descE, descriptors [4], "#A5"); Assert.AreSame (descF, descriptors [5], "#A6"); sorted = descriptors.Sort (new string [] { "B", "Foo", null, "A", "Boo" }, new CategoryComparer ()); Assert.AreSame (descA, descriptors [0], "#B1"); Assert.AreSame (descB, descriptors [1], "#B2"); Assert.AreSame (descC, descriptors [2], "#B3"); Assert.AreSame (descD, descriptors [3], "#B4"); Assert.AreSame (descE, descriptors [4], "#B5"); Assert.AreSame (descF, descriptors [5], "#B6"); Assert.AreSame (descA, sorted [0], "#C1"); Assert.AreSame (descE, sorted [1], "#C2"); Assert.AreSame (descC, sorted [2], "#C3"); Assert.AreSame (descB, sorted [3], "#C4"); Assert.AreSame (descD, sorted [4], "#C5"); Assert.AreSame (descF, sorted [5], "#C6"); sorted = descriptors.Sort ((string []) null, new CategoryComparer ()); Assert.AreSame (descA, descriptors [0], "#D1"); Assert.AreSame (descB, descriptors [1], "#D2"); Assert.AreSame (descC, descriptors [2], "#D3"); Assert.AreSame (descD, descriptors [3], "#D4"); Assert.AreSame (descE, descriptors [4], "#D5"); Assert.AreSame (descF, descriptors [5], "#D6"); Assert.AreSame (descC, sorted [0], "#E1"); Assert.AreSame (descA, sorted [1], "#E2"); Assert.AreSame (descB, sorted [2], "#E3"); Assert.AreSame (descE, sorted [3], "#E4"); Assert.AreSame (descD, sorted [4], "#E5"); Assert.AreSame (descF, sorted [5], "#E6"); sorted = descriptors.Sort (new string [] { "B", "Foo", null, "A", "Boo" }, (Comparer) null); Assert.AreSame (descA, descriptors [0], "#F1"); Assert.AreSame (descB, descriptors [1], "#F2"); Assert.AreSame (descC, descriptors [2], "#F3"); Assert.AreSame (descD, descriptors [3], "#F4"); Assert.AreSame (descE, descriptors [4], "#F5"); Assert.AreSame (descF, descriptors [5], "#F6"); Assert.AreSame (descA, sorted [0], "#G1"); Assert.AreSame (descE, sorted [1], "#G2"); Assert.AreSame (descB, sorted [2], "#G3"); Assert.AreSame (descD, sorted [3], "#G4"); Assert.AreSame (descC, sorted [4], "#G5"); Assert.AreSame (descF, sorted [5], "#G6"); sorted = descriptors.Sort ((string []) null, (Comparer) null); Assert.AreSame (descA, descriptors [0], "#H1"); Assert.AreSame (descB, descriptors [1], "#H2"); Assert.AreSame (descC, descriptors [2], "#H3"); Assert.AreSame (descD, descriptors [3], "#H4"); Assert.AreSame (descE, descriptors [4], "#H5"); Assert.AreSame (descF, descriptors [5], "#H6"); Assert.AreSame (descB, sorted [0], "#I1"); Assert.AreSame (descD, sorted [1], "#I2"); Assert.AreSame (descC, sorted [2], "#I3"); Assert.AreSame (descE, sorted [3], "#I4"); Assert.AreSame (descA, sorted [4], "#I5"); Assert.AreSame (descF, sorted [5], "#I6"); }
private void AssertReadOnly (EventDescriptorCollection descriptors, string testCase) { MockEventDescriptor desc = new MockEventDescriptor ( "Date", "NOW"); try { descriptors.Add (desc); Assert.Fail (testCase + "#1"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { descriptors.Add (null); Assert.Fail (testCase + "#2"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.Clear (); Assert.Fail (testCase + "#3"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.Insert (0, desc); Assert.Fail (testCase + "#4"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { descriptors.Insert (0, null); Assert.Fail (testCase + "#5"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.Remove (desc); Assert.Fail (testCase + "#6"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { descriptors.Remove (null); Assert.Fail (testCase + "#7"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { descriptors.RemoveAt (0); Assert.Fail (testCase + "#8"); } catch (NotSupportedException) { // read-only collection cannot be modified } IList list = (IList) descriptors; Assert.IsTrue (((IList) descriptors).IsReadOnly, testCase + "#9"); #if NET_2_0 Assert.IsTrue (((IList) descriptors).IsFixedSize, testCase + "#10"); #else Assert.IsFalse (((IList) descriptors).IsFixedSize, testCase + "#10"); #endif try { list.Add (desc); Assert.Fail (testCase + "#11"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list.Add (null); Assert.Fail (testCase + "#12"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.Clear (); Assert.Fail (testCase + "#13"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.Insert (0, desc); Assert.Fail (testCase + "#14"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list.Insert (0, null); Assert.Fail (testCase + "#15"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.Remove (desc); Assert.Fail (testCase + "#16"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list.Remove (null); Assert.Fail (testCase + "#17"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list.RemoveAt (0); Assert.Fail (testCase + "#18"); } catch (NotSupportedException) { // read-only collection cannot be modified } try { list[0] = desc; Assert.Fail (testCase + "#19"); } catch (NotSupportedException) { // read-only collection cannot be modified } // ensure read-only check if performed before value is checked try { list[0] = null; Assert.Fail (testCase + "#20"); } catch (NotSupportedException) { // read-only collection cannot be modified } }
/// <devdoc> /// Retrieves events that satisfy all of the passed-in attributes. /// For an event to satisfy a particular attribute, the attribute must be /// present in the event's attribute list, or the attribute must match it's /// own default. The returned array is sorted based on the sort parameter. /// </devdoc> public EventDescriptorCollection GetEvents(object component, Attribute[] attributes, bool noFilter) { // Worst case event collision scenario is two sets of events. Much cheaper than // a constant lock. // if (this.events == null) { this.events = new EventDescriptorCollection(new MemberList(this).GetEvents(), true); } EventDescriptorCollection filteredEvents = events; if (component is IComponent) { ITypeDescriptorFilterService tf = (ITypeDescriptorFilterService)GetService(component, typeof(ITypeDescriptorFilterService)); if (!noFilter && tf != null) { // The component's site is interested in filtering events. See if we // have filtered them before. If so, then we're done. Otherwise we // need to filter. // IDictionaryService ds = (IDictionaryService)GetService(component, typeof(IDictionaryService)); if (ds != null) { EventDescriptorCollection savedEvents = null; lock(ds) { savedEvents = (EventDescriptorCollection)ds.GetValue(typeof(EventDescriptorCollection)); } if (savedEvents != null) { // Check that the filter that was used to create these attributes is the same // filter we currently have. People may replace the filter, and if we do // we must refresh the cache. // object savedFilter = ds.GetValue(typeof(ITypeDescriptorFilterService)); if (savedFilter == null || savedFilter == tf) { filteredEvents = savedEvents; } } } if (filteredEvents == events) { Hashtable filterTable = new Hashtable(events.Count); if (events != null) { foreach (EventDescriptor ev in events) { filterTable[ev.Name] = ev; } } bool cache = tf.FilterEvents((IComponent)component, filterTable); EventDescriptor[] temp = new EventDescriptor[filterTable.Values.Count]; filterTable.Values.CopyTo(temp, 0); filteredEvents = new EventDescriptorCollection(temp, true); if (ds != null && cache) { lock(ds) { ds.SetValue(typeof(EventDescriptorCollection), filteredEvents); ds.SetValue(typeof(ITypeDescriptorFilterService), tf); } } } } } if (attributes != null && attributes.Length > 0) { ArrayList list = new ArrayList(filteredEvents); FilterMembers(typeof(EventDescriptor), list, attributes); EventDescriptor[] temp = new EventDescriptor[list.Count]; list.CopyTo(temp, 0); filteredEvents = new EventDescriptorCollection(temp, true); } return filteredEvents; }
internal EventDescriptorCollection FilterEvents(object component, Attribute[] attributes, EventDescriptorCollection events) { EventDescriptorCollection filteredEvents = events; if (component is IComponent) { ITypeDescriptorFilterService tf = (ITypeDescriptorFilterService)GetService(component, typeof(ITypeDescriptorFilterService)); if (tf != null) { Hashtable filterTable = new Hashtable(events.Count); if (events != null) { foreach (EventDescriptor ev in events) { filterTable[ev.Name] = ev; } } bool cache = tf.FilterEvents((IComponent)component, filterTable); EventDescriptor[] temp = new EventDescriptor[filterTable.Values.Count]; filterTable.Values.CopyTo(temp, 0); filteredEvents = new EventDescriptorCollection(temp, true); } } if (attributes != null && attributes.Length > 0) { ArrayList list = new ArrayList(filteredEvents); FilterMembers(typeof(EventDescriptor), list, attributes); EventDescriptor[] temp = new EventDescriptor[list.Count]; list.CopyTo(temp, 0); filteredEvents = new EventDescriptorCollection(temp, true); } return filteredEvents; }
public override EventDescriptorCollection GetEvents () { if (_events != null) return _events; bool cache = true; EventInfo[] events = _component.GetType().GetEvents (); Hashtable t = new Hashtable (); foreach (EventInfo ev in events) t [ev.Name] = new ReflectionEventDescriptor (ev); if (_component.Site != null) { ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService)); if (filter != null) cache = filter.FilterEvents (_component, t); } ArrayList atts = new ArrayList (); atts.AddRange (t.Values); EventDescriptorCollection attCol = new EventDescriptorCollection (atts); if (cache) _events = attCol; return attCol; }
/// Converts a set of events to a set of properties. PropertyDescriptorCollection IEventBindingService.GetEventProperties(EventDescriptorCollection events) { if (events == null) { throw new ArgumentNullException("events"); } PropertyDescriptor[] props = new PropertyDescriptor[events.Count]; // We cache the property descriptors here for speed. Create those for // events that we don't have yet. // if (_eventProperties == null) { _eventProperties = new Hashtable(); } for (int i = 0; i < events.Count; i++) { object eventHashCode = GetEventDescriptorHashCode(events[i]); props[i] = (PropertyDescriptor)_eventProperties[eventHashCode]; if (props[i] == null) { props[i] = new EventPropertyDescriptor(events[i], this); _eventProperties[eventHashCode] = props[i]; } } return new PropertyDescriptorCollection(props); }
/// <devdoc> /// Retrieves the events for this type. /// </devdoc> internal EventDescriptorCollection GetEvents() { // Worst case collision scenario: we don't want the perf hit // of taking a lock, so if we collide we will query for // events twice. Not a big deal. // if (_events == null) { TypeDescriptor.Trace("Events : Building collection for {0}", _type.Name); EventDescriptor[] eventArray; Dictionary<string, EventDescriptor> eventList = new Dictionary<string, EventDescriptor>(16); Type baseType = _type; Type objType = typeof(object); do { eventArray = ReflectGetEvents(baseType); foreach(EventDescriptor ed in eventArray) { if (!eventList.ContainsKey(ed.Name)) { eventList.Add(ed.Name, ed); } } baseType = baseType.BaseType; } while(baseType != null && baseType != objType); eventArray = new EventDescriptor[eventList.Count]; eventList.Values.CopyTo(eventArray, 0); _events = new EventDescriptorCollection(eventArray, true); } return _events; }
/// <devdoc> /// Gets a collection of events for a specified type of /// component using a specified array of attributes as a filter. /// </devdoc> public static EventDescriptorCollection GetEvents(Type componentType, Attribute[] attributes) { if (componentType == null) { Debug.Fail("COMPAT: Returning an empty collection, but you should not pass null here"); return new EventDescriptorCollection(null, true); } EventDescriptorCollection events = GetDescriptor(componentType, "componentType").GetEvents(attributes); if (attributes != null && attributes.Length > 0) { ArrayList filteredEvents = FilterMembers(events, attributes); if (filteredEvents != null) { events = new EventDescriptorCollection((EventDescriptor[])filteredEvents.ToArray(typeof(EventDescriptor)), true); } } DebugValidate(events, componentType, attributes); return events; }
PropertyDescriptorCollection IEventBindingService.GetEventProperties(EventDescriptorCollection e) { if (!(this.GetCodeDocumentLanguage() is ICodeBehindDocumentLanguage)) { return new PropertyDescriptorCollection(null); } PropertyDescriptor[] properties = new PropertyDescriptor[e.Count]; for (int i = 0; i < e.Count; i++) { properties[i] = ((IEventBindingService) this).GetEventProperty(e[i]); } return new PropertyDescriptorCollection(properties); }
/// <devdoc> /// This is the last stage in our filtering pipeline. Here, we apply any /// user-defined filter. /// </devdoc> private static ICollection PipelineAttributeFilter(int pipelineType, ICollection members, Attribute[] filter, object instance, IDictionary cache) { Debug.Assert(pipelineType != PIPELINE_ATTRIBUTES, "PipelineAttributeFilter is not supported for attributes"); IList list = members as ArrayList; if (filter == null || filter.Length == 0) { return members; } // Now, check our cache. The cache state is only valid // if the data coming into us is read-only. If it is read-write, // that means something higher in the pipeline has already changed // it so we must recompute anyway. // if (cache != null && (list == null || list.IsReadOnly)) { AttributeFilterCacheItem filterCache = cache[_pipelineAttributeFilterKeys[pipelineType]] as AttributeFilterCacheItem; if (filterCache != null && filterCache.IsValid(filter)) { return filterCache.FilteredMembers; } } // Our cache did not contain the correct state, so generate it. // if (list == null || list.IsReadOnly) { Trace("Pipeline : Filter needs to create member list for {0}", instance.GetType().Name); list = new ArrayList(members); } ArrayList filterResult = FilterMembers(list, filter); if (filterResult != null) list = filterResult; // And, if we have a cache, store the updated state into it for future reference. // if (cache != null) { ICollection cacheValue; switch(pipelineType) { case PIPELINE_PROPERTIES: PropertyDescriptor[] propArray = new PropertyDescriptor[list.Count]; list.CopyTo(propArray, 0); cacheValue = new PropertyDescriptorCollection(propArray, true); break; case PIPELINE_EVENTS: EventDescriptor[] eventArray = new EventDescriptor[list.Count]; list.CopyTo(eventArray, 0); cacheValue = new EventDescriptorCollection(eventArray, true); break; default: Debug.Fail("unknown pipeline type"); cacheValue = null; break; } Trace("Pipeline : Attribute Filter results being cached for {0}", instance.GetType().Name); AttributeFilterCacheItem filterCache = new AttributeFilterCacheItem(filter, cacheValue); cache[_pipelineAttributeFilterKeys[pipelineType]] = filterCache; } return list; }
public static EventDescriptorCollection GetEvents(object component, Attribute[] attributes, bool noCustomTypeDesc) { if (component == null) { Debug.Fail("COMPAT: Returning an empty collection, but you should not pass null here"); return new EventDescriptorCollection(null, true); } // We create a sort of pipeline for mucking with metadata. The pipeline // goes through the following process: // // 1. Merge metadata from extenders. // 2. Allow services to filter the metadata // 3. If an attribute filter was specified, apply that. // // The goal here is speed. We get speed by not copying or // allocating memory. We do this by allowing each phase of the // pipeline to cache its data in the object cache. If // a phase makes a change to the results, this change must cause // successive phases to recompute their results as well. "Results" is // always a collection, and the various stages of the pipeline may // replace or modify this collection (depending on if it's a // read-only IList or not). It is possible for the orignal // descriptor or attribute collection to pass through the entire // pipeline without modification. // ICustomTypeDescriptor typeDesc = GetDescriptor(component, noCustomTypeDesc); ICollection results; // If we are handed a custom type descriptor we have several choices of action // we can take. If noCustomTypeDesc is true, it means that the custom type // descriptor is trying to find a baseline set of events. In this case // we should merge in extended events, but we do not let designers filter // because we're not done with the event set yet. If noCustomTypeDesc // is false, we don't do extender events because the custom type descriptor // has already added them. In this case, we are doing a final pass so we // want to apply filtering. Finally, if the incoming object is not a custom // type descriptor, we do extenders and the filter. // if (component is ICustomTypeDescriptor) { results = typeDesc.GetEvents(attributes); if (noCustomTypeDesc) { ICustomTypeDescriptor extDesc = GetExtendedDescriptor(component); if (extDesc != null) { ICollection extResults = extDesc.GetEvents(attributes); results = PipelineMerge(PIPELINE_EVENTS, results, extResults, component, null); } } else { results = PipelineFilter(PIPELINE_EVENTS, results, component, null); results = PipelineAttributeFilter(PIPELINE_EVENTS, results, attributes, component, null); } } else { IDictionary cache = GetCache(component); results = typeDesc.GetEvents(attributes); results = PipelineInitialize(PIPELINE_EVENTS, results, cache); ICustomTypeDescriptor extDesc = GetExtendedDescriptor(component); if (extDesc != null) { ICollection extResults = extDesc.GetEvents(attributes); results = PipelineMerge(PIPELINE_EVENTS, results, extResults, component, cache); } results = PipelineFilter(PIPELINE_EVENTS, results, component, cache); results = PipelineAttributeFilter(PIPELINE_EVENTS, results, attributes, component, cache); } EventDescriptorCollection evts = results as EventDescriptorCollection; if (evts == null) { Trace("Events : Allocated new event collection for {0}", component.GetType().Name); EventDescriptor[] eventArray = new EventDescriptor[results.Count]; results.CopyTo(eventArray, 0); evts = new EventDescriptorCollection(eventArray, true); } DebugValidate(evts, component, attributes, noCustomTypeDesc); return evts; }
[Test] // this [String] public void Indexer2 () { EventDescriptor descA = new MockEventDescriptor ("hehe_\u0061\u030a", null); EventDescriptor descB = new MockEventDescriptor ("heh_\u00e5", null); EventDescriptor descC = new MockEventDescriptor ("Foo", null); EventDescriptor descD = new MockEventDescriptor ("FOo", null); EventDescriptor descE = new MockEventDescriptor ("Aim", null); EventDescriptor descF = new MockEventDescriptor ("Bar", null); EventDescriptorCollection col = new EventDescriptorCollection ( new EventDescriptor [] { descA, descB, descC, descD, descE, descF }); #if NET_2_0 Assert.IsNull (col ["heh_\u0061\u030a"], "#1"); Assert.IsNull (col ["hehe_\u00e5"], "#2"); #else Assert.AreSame (descB, col ["heh_\u0061\u030a"], "#1"); Assert.AreSame (descA, col ["hehe_\u00e5"], "#2"); #endif Assert.AreSame (descA, col ["hehe_\u0061\u030a"], "#3"); Assert.AreSame (descB, col ["heh_\u00e5"], "#4"); Assert.IsNull (col ["foo"], "#5"); Assert.AreSame (descD, col ["FOo"], "#6"); Assert.IsNull (col ["fOo"], "#7"); Assert.IsNull (col ["AIm"], "#8"); Assert.IsNull (col ["AiM"], "#9"); Assert.AreSame (descE, col ["Aim"], "#10"); Assert.IsNull (col [(string) null], "#11"); }
/// <devdoc> /// Metdata filtering is the third stage of our pipeline. /// In this stage we check to see if the given object is a /// sited component that provides the ITypeDescriptorFilterService /// object. If it does, we allow the TDS to filter the metadata. /// This will use the cache, if available, to store filtered /// metdata. /// </devdoc> private static ICollection PipelineFilter(int pipelineType, ICollection members, object instance, IDictionary cache) { IComponent component = instance as IComponent; ITypeDescriptorFilterService componentFilter = null; if (component != null) { ISite site = component.Site; if (site != null) { componentFilter = site.GetService(typeof(ITypeDescriptorFilterService)) as ITypeDescriptorFilterService; } } // If we have no filter, there is nothing for us to do. // IList list = members as ArrayList; if (componentFilter == null) { Debug.Assert(cache == null || list == null || !cache.Contains(_pipelineFilterKeys[pipelineType]), "Earlier pipeline stage should have removed our cache"); return members; } // Now, check our cache. The cache state is only valid // if the data coming into us is read-only. If it is read-write, // that means something higher in the pipeline has already changed // it so we must recompute anyway. // if (cache != null && (list == null || list.IsReadOnly)) { FilterCacheItem cacheItem = cache[_pipelineFilterKeys[pipelineType]] as FilterCacheItem; if (cacheItem != null && cacheItem.IsValid(componentFilter)) { return cacheItem.FilteredMembers; } } // Cache either is dirty or doesn't exist. Re-filter the members. // We need to build an IDictionary of key->value pairs and invoke // Filter* on the filter service. // OrderedDictionary filterTable = new OrderedDictionary(members.Count); bool cacheResults; switch(pipelineType) { case PIPELINE_ATTRIBUTES: foreach(Attribute attr in members) { filterTable[attr.TypeId] = attr; } cacheResults = componentFilter.FilterAttributes(component, filterTable); break; case PIPELINE_PROPERTIES: case PIPELINE_EVENTS: foreach(MemberDescriptor desc in members) { string descName = desc.Name; // We must handle the case of duplicate property names // because extender providers can provide any arbitrary // name. Our rule for this is simple: If we find a // duplicate name, resolve it back to the extender // provider that offered it and append "_" + the // provider name. If the provider has no name, // then append the object hash code. // if (filterTable.Contains(descName)) { // First, handle the new property. Because // of the order in which we added extended // properties earlier in the pipeline, we can be // sure that the new property is an extender. We // cannot be sure that the existing property // in the table is an extender, so we will // have to check. // string suffix = GetExtenderCollisionSuffix(desc); Debug.Assert(suffix != null, "Name collision with non-extender property."); if (suffix != null) { filterTable[descName + suffix] = desc; } // Now, handle the original property. // MemberDescriptor origDesc = (MemberDescriptor)filterTable[descName]; suffix = GetExtenderCollisionSuffix(origDesc); if (suffix != null) { filterTable.Remove(descName); filterTable[origDesc.Name + suffix] = origDesc; } } else { filterTable[descName] = desc; } } if (pipelineType == PIPELINE_PROPERTIES) { cacheResults = componentFilter.FilterProperties(component, filterTable); } else { cacheResults = componentFilter.FilterEvents(component, filterTable); } break; default: Debug.Fail("unknown pipeline type"); cacheResults = false; break; } // See if we can re-use the IList were were passed. If we can, // it is more efficient to re-use its slots than to generate new ones. // if (list == null || list.IsReadOnly) { Trace("Pipeline : Filter needs to create member list for {0}", instance.GetType().Name); list = new ArrayList(filterTable.Values); } else { list.Clear(); foreach(object obj in filterTable.Values) { list.Add(obj); } } // Component filter has requested that we cache these // new changes. We store them as a correctly typed collection // so on successive invocations we can simply return. Note that // we always return the IList so that successive stages in the // pipeline can modify it. // if (cacheResults && cache != null) { ICollection cacheValue; switch(pipelineType) { case PIPELINE_ATTRIBUTES: Attribute[] attrArray = new Attribute[list.Count]; try { list.CopyTo(attrArray, 0); } catch(InvalidCastException) { throw new ArgumentException(SR.GetString(SR.TypeDescriptorExpectedElementType, typeof(Attribute).FullName)); } cacheValue = new AttributeCollection(attrArray); break; case PIPELINE_PROPERTIES: PropertyDescriptor[] propArray = new PropertyDescriptor[list.Count]; try { list.CopyTo(propArray, 0); } catch(InvalidCastException) { throw new ArgumentException(SR.GetString(SR.TypeDescriptorExpectedElementType, typeof(PropertyDescriptor).FullName)); } cacheValue = new PropertyDescriptorCollection(propArray, true); break; case PIPELINE_EVENTS: EventDescriptor[] eventArray = new EventDescriptor[list.Count]; try { list.CopyTo(eventArray, 0); } catch(InvalidCastException) { throw new ArgumentException(SR.GetString(SR.TypeDescriptorExpectedElementType, typeof(EventDescriptor).FullName)); } cacheValue = new EventDescriptorCollection(eventArray, true); break; default: Debug.Fail("unknown pipeline type"); cacheValue = null; break; } Trace("Pipeline : Filter results being cached for {0}", instance.GetType().Name); FilterCacheItem cacheItem = new FilterCacheItem(componentFilter, cacheValue); cache[_pipelineFilterKeys[pipelineType]] = cacheItem; cache.Remove(_pipelineAttributeFilterKeys[pipelineType]); } return list; }
public void ReadOnly () { EventDescriptorCollection descriptors = new EventDescriptorCollection ( (EventDescriptor []) null, true); AssertReadOnly (descriptors, "ReadOnly"); }
private static void DebugValidate(EventDescriptorCollection events, Type type, Attribute[] attributes) { #if DEBUG if (!DebugShouldValidate(type)) return; EventDescriptorCollection debugEvents = DebugTypeDescriptor.GetEvents(type, attributes); Debug.Assert(debugEvents.Count == events.Count, "TypeDescriptor engine Validation Failure. Event counts differ."); foreach(EventDescriptor debugEvt in debugEvents) { EventDescriptor evt = null; foreach(EventDescriptor realEvt in events) { if (realEvt.Name.Equals(debugEvt.Name) && realEvt.EventType == debugEvt.EventType && realEvt.ComponentType == debugEvt.ComponentType) { evt = realEvt; break; } } Debug.Assert(evt != null, "TypeDescriptor engine Validation Failure. Event " + debugEvt.Name + " does not exist or is of the wrong type."); if (evt != null) { AttributeCollection attrs = evt.Attributes; if (attrs[typeof(AttributeProviderAttribute)] == null) { AttributeCollection debugAttrs = debugEvt.Attributes; DebugValidate(evt.EventType, attrs, debugAttrs); } } } #endif }
[Test] // Sort (IComparer) public void Sort3 () { EventDescriptorCollection descriptors; EventDescriptorCollection sorted; EventDescriptor descA = new MockEventDescriptor ("Foo", "B"); EventDescriptor descB = new MockEventDescriptor ("Aim", "C"); EventDescriptor descC = new MockEventDescriptor ("Bim", "A"); EventDescriptor descD = new MockEventDescriptor ("AIm", "E"); EventDescriptor descE = new MockEventDescriptor ("Boo", "D"); EventDescriptor descF = new MockEventDescriptor ("FOo", "F"); EventDescriptor [] props = new EventDescriptor [] { descA, descB, descC, descD, descE, descF }; descriptors = new EventDescriptorCollection (props); Assert.AreSame (descA, descriptors [0], "#A1"); Assert.AreSame (descB, descriptors [1], "#A2"); Assert.AreSame (descC, descriptors [2], "#A3"); Assert.AreSame (descD, descriptors [3], "#A4"); Assert.AreSame (descE, descriptors [4], "#A5"); Assert.AreSame (descF, descriptors [5], "#A6"); sorted = descriptors.Sort (new CategoryComparer ()); Assert.AreSame (descA, descriptors [0], "#B1"); Assert.AreSame (descB, descriptors [1], "#B2"); Assert.AreSame (descC, descriptors [2], "#B3"); Assert.AreSame (descD, descriptors [3], "#B4"); Assert.AreSame (descE, descriptors [4], "#B5"); Assert.AreSame (descF, descriptors [5], "#B6"); Assert.AreSame (descC, sorted [0], "#C1"); Assert.AreSame (descA, sorted [1], "#C2"); Assert.AreSame (descB, sorted [2], "#C3"); Assert.AreSame (descE, sorted [3], "#C4"); Assert.AreSame (descD, sorted [4], "#C5"); Assert.AreSame (descF, sorted [5], "#C6"); sorted = descriptors.Sort ((Comparer) null); Assert.AreSame (descA, descriptors [0], "#D1"); Assert.AreSame (descB, descriptors [1], "#D2"); Assert.AreSame (descC, descriptors [2], "#D3"); Assert.AreSame (descD, descriptors [3], "#D4"); Assert.AreSame (descE, descriptors [4], "#D5"); Assert.AreSame (descF, descriptors [5], "#D6"); Assert.AreSame (descB, sorted [0], "#E1"); Assert.AreSame (descD, sorted [1], "#E2"); Assert.AreSame (descC, sorted [2], "#E3"); Assert.AreSame (descE, sorted [3], "#E4"); Assert.AreSame (descA, sorted [4], "#E5"); Assert.AreSame (descF, sorted [5], "#E6"); }