/// <summary> /// Returns true, iff this AttributeSource contains the passed-in attribute type. /// </summary> public virtual bool HasAttribute(Type attrType) { if (attrType == null) { throw new ArgumentNullException("attrType"); } return(attributes.Contains(attrType)); }
/// <summary> /// <b>Expert:</b> Adds a custom AttributeImpl instance with one or more Attribute interfaces. /// <p><font color="red"><b>Please note:</b> It is not guaranteed, that <c>attr</c> is added to /// the <c>AttributeSource</c>, because the provided attributes may already exist. /// You should always retrieve the wanted attributes using <see cref="GetAttribute{T}"/> after adding /// with this method and cast to your class. /// The recommended way to use custom implementations is using an <see cref="AttributeFactory"/> /// </font></p> /// </summary> public virtual void AddAttributeImpl(Attribute attr) { Type attrType = attr.GetType(); if (attributeImpls.Contains(attrType)) { return; } LinkedList <WeakReference> foundInterfaces; lock (knownImplClasses) { foundInterfaces = knownImplClasses[attrType]; if (foundInterfaces == null) { // we have a strong reference to the class instance holding all interfaces in the list (parameter "attr"), // so all WeakReferences are never evicted by GC knownImplClasses.Add(attrType, foundInterfaces = new LinkedList <WeakReference>()); // find all interfaces that this attribute instance implements // and that extend the Attribute interface var type = attrType; do { var interfaces = type.GetInterfaces(); foreach (var curInterface in interfaces) { if (curInterface != typeof(IAttribute) && typeof(IAttribute).IsAssignableFrom(curInterface)) { foundInterfaces.AddLast(new WeakReference(curInterface)); } } type = type.BaseType; }while (type != null); } } // add all interfaces of this AttributeImpl to the maps foreach (var curInterfaceRef in foundInterfaces) { Type curInterface = (Type)curInterfaceRef.Target; System.Diagnostics.Debug.Assert(curInterface != null, "We have a strong reference on the class holding the interfaces, so they should never get evicted"); // Attribute is a superclass of this interface if (!attributes.ContainsKey(curInterface)) { // invalidate state to force recomputation in captureState() this.currentState[0] = null; attributes.Add(new AttributeImplItem(curInterface, attr)); if (!attributeImpls.ContainsKey(attrType)) { attributeImpls.Add(new AttributeImplItem(attrType, attr)); } } } }
/// <summary> /// <b>Expert:</b> Adds a custom AttributeImpl instance with one or more Attribute interfaces. /// <p><font color="red"><b>Please note:</b> It is not guaranteed, that <c>att</c> is added to /// the <c>AttributeSource</c>, because the provided attributes may already exist. /// You should always retrieve the wanted attributes using <see cref="GetAttribute{T}"/> after adding /// with this method and cast to your class. /// The recommended way to use custom implementations is using an <see cref="AttributeFactory"/> /// </font></p> /// </summary> public virtual void AddAttributeImpl(Attribute att) { System.Type clazz = att.GetType(); if (attributeImpls.Contains(clazz)) { return; } System.Collections.Generic.LinkedList <WeakReference> foundInterfaces; lock (knownImplClasses) { foundInterfaces = knownImplClasses[clazz]; if (foundInterfaces == null) { // we have a strong reference to the class instance holding all interfaces in the list (parameter "att"), // so all WeakReferences are never evicted by GC knownImplClasses.Add(clazz, foundInterfaces = new LinkedList <WeakReference>()); // find all interfaces that this attribute instance implements // and that extend the Attribute interface System.Type actClazz = clazz; do { System.Type[] interfaces = actClazz.GetInterfaces(); for (int i = 0; i < interfaces.Length; i++) { System.Type curInterface = interfaces[i]; if (curInterface != typeof(IAttribute) && typeof(IAttribute).IsAssignableFrom(curInterface)) { foundInterfaces.AddLast(new WeakReference(curInterface)); } } actClazz = actClazz.BaseType; }while (actClazz != null); } } // add all interfaces of this AttributeImpl to the maps foreach (var curInterfaceRef in foundInterfaces) { System.Type curInterface = (System.Type)curInterfaceRef.Target; System.Diagnostics.Debug.Assert(curInterface != null, "We have a strong reference on the class holding the interfaces, so they should never get evicted"); // Attribute is a superclass of this interface if (!attributes.ContainsKey(curInterface)) { // invalidate state to force recomputation in captureState() this.currentState[0] = null; attributes.Add(new AttributeImplItem(curInterface, att)); if (!attributeImpls.ContainsKey(clazz)) { attributeImpls.Add(new AttributeImplItem(clazz, att)); } } } }