/*
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);
}
}
}
}