Attributes are not meant for playing functional role. You need to write code using reflection somewhere in your project that reads type-meta-data of classes [and props, methods, etc.] and finds attributes applied to it. Based on the attributes applied you can take decisions at run-time about what to do with that. Generally this is done in base classes of your library.
As an example in our projects we have an attribute called 'Searchable'. This attribute is applied to properties of business objects which need to be included in search. When the client calls Search method we filter out all props that are decorated with Searchable attribute and then construct query to do search on the database. Practically we dont have any code related to search functionality in SearchableAttribute class - in fact there's no code at all in SearchableAttribute class.
Example Code:
SearchableAttribute
/// <summary>
/// Holds mapping information of searchable fields of business objects.
/// </summary>
[global::System.AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class SearchableAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the SearchableAttributeAttribute class.
/// </summary>
public SearchableAttribute()
{
}
}
A method in business object base class
/// <summary>
/// Provides collection of all Searchable Fields.
/// </summary>
/// <returns>DataField collection</returns>
public IQueryable<DataField> GetSearchableDataFields()
{
PropertyInfo[] properties =
this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
var entityFields = from PropertyInfo property in properties
where property.GetCustomAttributes(typeof(SearchableAttribute), true).Length > 0
select
new DataField(
property,
(SearchableAttribute)property.GetCustomAttributes(typeof(SearchableAttribute), true)[0]);
return entityFields.AsQueryable();
}