Files
DP44/Common/DTS.Common.Utilities/AttributeExtractor.cs
2026-04-17 14:55:32 -04:00

142 lines
6.6 KiB
C#

/*
AttributeExtractor.cs
Copyright © 2008
Diversified Technical Systems
All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Reflection;
namespace DTS.Common.Utilities
{
/// <summary>
/// Class to ease extracting custom attributes from their attached objects.
/// </summary>
/// <typeparam name="TAttributeType"></typeparam>
public class AttributeExtractor<TAttributeType> : Exceptional
{
/// <summary>
/// Extract an attribute of this class' declared type from the specified target.
/// </summary>
///
/// <param name="target">
/// The <see cref="Object"/> to which the sought attribute is attached.
/// </param>
///
/// <returns>
/// The attribute type specified upon AttributeExtractor creation.
/// </returns>
///
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 + "\"") : "<<NULL>>"), ex);
}
}
/// <summary>
/// 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.
/// </summary>
///
/// <param name="propertyContainer">
/// The <see cref="Object"/> that contains the property under query.
/// </param>
///
/// <param name="propertyName">
/// The <see cref="string"/> name of the property to be queried.
/// </param>
///
/// <returns>
/// A <see cref="T:List"/> of attached attributes of the type specified during the creation
/// of this instance of AttributeExtractor.
/// </returns>
///
public List<TAttributeType> 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<TAttributeType>(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 + "\"") : "<<NULL>>") + " on object " + (null != (propertyContainerString = propertyContainer.ToString()) ? ("\"" + propertyContainerString + "\"") : "<<NULL>>"), ex);
}
}
/// <summary>
/// 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.
/// </summary>
///
/// <param name="propertyContainer">
/// The <see cref="Object"/> that contains the property under query.
/// </param>
///
/// <param name="propertyName">
/// The <see cref="string"/> name of the property to be queried.
/// </param>
///
/// <returns>
/// An attribute of the type specified during the creation of this instance of AttributeExtractor,
/// if one is attached; null otherwise.
/// </returns>
///
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 + "\"") : "<<NULL>>") + " on object " + (null != (propertyContainerString = propertyContainer.ToString()) ? ("\"" + propertyContainerString + "\"") : "<<NULL>>"), ex);
}
}
}
}