/* AttributeExtractor.cs Copyright © 2008 Diversified Technical Systems All Rights Reserved */ using System; using System.Collections.Generic; using System.Reflection; namespace DTS.Common.Utilities { /// /// Class to ease extracting custom attributes from their attached objects. /// /// public class AttributeExtractor : Exceptional { /// /// Extract an attribute of this class' declared type from the specified target. /// /// /// /// The to which the sought attribute is attached. /// /// /// /// The attribute type specified upon AttributeExtractor creation. /// /// public TAttributeType ExtractAttachedAttributeFromObject(object target) { try { ICustomAttributeProvider info = target.GetType(); var attributes = info.GetCustomAttributes(typeof(TAttributeType), false) as TAttributeType[]; if (attributes != null) { if (attributes.Length < 1) throw new Exception("attempted to extract non-existent \"" + typeof(TAttributeType) + "\" attribute"); if (attributes.Length > 1) throw new Exception("attempted to extract \"" + typeof(TAttributeType) + "\" attribute from object decorated with multiple attributes; there should be only one"); } return attributes[0]; } catch (System.Exception ex) { string targetString; throw new Exception("encountered problem extracting attached \"" + typeof(TAttributeType) + "\"attribute value from object " + (null != (targetString = target.ToString()) ? ("\"" + targetString + "\"") : "<>"), ex); } } /// /// Extract a list of attached attributes from the specified property. An object and property name /// must be supplied, for attempts to directly reference the property will result in get/set invocation. /// /// /// /// The that contains the property under query. /// /// /// /// The name of the property to be queried. /// /// /// /// A of attached attributes of the type specified during the creation /// of this instance of AttributeExtractor. /// /// public List ExtractAttachedAttributesFromProperty(object propertyContainer, string propertyName) { try { if (null == propertyContainer) throw new ArgumentNullException("cannot extract property from null property container reference"); if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("cannot extract property with null/empty string name"); try { return new List(propertyContainer.GetType().GetProperty(propertyName).GetCustomAttributes(typeof(TAttributeType), false) as TAttributeType[]); } catch (NullReferenceException) { throw new Exception("attribute does not exist"); } } catch (System.Exception ex) { string propertyContainerString; throw new Exception("encountered problem extracting attached XML tag attribute values from property " + (null != propertyName ? ("\"" + propertyName + "\"") : "<>") + " on object " + (null != (propertyContainerString = propertyContainer.ToString()) ? ("\"" + propertyContainerString + "\"") : "<>"), ex); } } /// /// Extract an attached attributes from the specified property of the type declared during the /// creation of this instance of AttributeExtractor. An object and property name must be supplied, /// for attempts to directly reference the property will result in get/set invocation. /// /// /// /// The that contains the property under query. /// /// /// /// The name of the property to be queried. /// /// /// /// An attribute of the type specified during the creation of this instance of AttributeExtractor, /// if one is attached; null otherwise. /// /// public TAttributeType ExtractAttachedAttributeFromProperty(object propertyContainer, string propertyName) { try { if (null == propertyContainer) throw new ArgumentNullException("cannot extract property from null property container reference"); if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("cannot extract property with null/empty string name"); var attributes = ExtractAttachedAttributesFromProperty(propertyContainer, propertyName); if (attributes.Count < 1) throw new Exception("attempted to extract non-existent \"" + typeof(TAttributeType) + "\" attribute"); if (attributes.Count > 1) throw new Exception("attempted to extract \"" + typeof(TAttributeType) + "\" attribute from object decorated with multiple attributes; there should be only one"); return attributes[0]; } catch (System.Exception ex) { string propertyContainerString; throw new Exception("encountered problem extracting attached XML tag attribute value from property " + (null != propertyName ? ("\"" + propertyName + "\"") : "<>") + " on object " + (null != (propertyContainerString = propertyContainer.ToString()) ? ("\"" + propertyContainerString + "\"") : "<>"), ex); } } } }