Skip to content

Instantly share code, notes, and snippets.

@cliss
Created August 2, 2013 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cliss/6139960 to your computer and use it in GitHub Desktop.
Save cliss/6139960 to your computer and use it in GitHub Desktop.
Example of a C# class, CarouselItem, that uses attributes to decorate fields/ivars and also properties. The attribute is Column, which corresponds to a custom class I wrote which is called ColumnAttribute (convention dictates this), which is shown below as well.
[XmlRoot(ElementName="Item")]
public class CarouselItem
{
#region Fields
#pragma warning disable 649
[Column("URL")]
private string _url;
[Column("AnnouncementImage")]
private string _image;
[Column("Title")]
private string _title;
#pragma warning restore 649
#endregion Fields
#region Properties
#region Decomposing Properties
/* Irrelevant stuff */
#endregion Decomposing Properties
[Column("ID")]
public int Id { get; set; }
[Column]
public int DisplaySortOrder { get; set; }
[Column]
public bool IncludeInRollup { get; set; }
[Column]
public DateTime StartDate { get; set; }
[Column("_EndDate")]
public DateTime EndDate { get; set; }
[Column("OpenLinkInNewWindow")]
public bool OpenInNewWindow { get; set; }
[Column]
public string CarouselText { get; set; }
#endregion Properties
#region Methods
public CarouselItem()
{
}
public CarouselItem(SPListItem item)
{
ColumnAttribute.SetAllValues(this, s =>
{
if (item.Fields.ContainsField(s))
{
return item[s];
}
return null;
});
}
#endregion Methods
}
/// <summary>
/// Attribute to define a column associated with a field or property.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
#region Instance
public string Column { get; set; }
/// <summary>
/// Constructor. By not specifying a column name, the assumption
/// is that the member's name matches the column name.
/// </summary>
public ColumnAttribute()
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="column">Name of the column associated with this member.</param>
public ColumnAttribute(string column)
{
this.Column = column;
}
#endregion Instance
#region Static
/// <summary>
/// Gets a column by a property or field. If the column attribute is specified
/// without a column name, the member's name is assumed.
/// </summary>
/// <param name="info">Property or field to look up column information for</param>
/// <returns>Name of the column if found; <c>null</c> otherwise.</returns>
public static string GetColumn(MemberInfo info)
{
string retVal = null;
var attrib = info.GetCustomAttributes(true).OfType<ColumnAttribute>().FirstOrDefault();
if (attrib != null)
{
retVal = attrib.Column ?? info.Name;
}
return retVal;
}
/// <summary>
/// Sets all the values on an object by matching properties with values.
/// </summary>
/// <param name="o">Object to set values on.</param>
/// <param name="valueFetcher">Function to get values by column name</param>
public static void SetAllValues(object o, Func<string, object> valueFetcher)
{
foreach (var property in o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
string column = ColumnAttribute.GetColumn(property);
if (!string.IsNullOrEmpty(column) && property.CanWrite)
{
property.SetValue(o, valueFetcher(column), null);
}
}
foreach (var field in o.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
string column = ColumnAttribute.GetColumn(field);
if (!string.IsNullOrEmpty(column))
{
field.SetValue(o, valueFetcher(column));
}
}
}
#endregion Static
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment