I have a generic class that I am using Reflection to pull out the properties of the type of the generic and looking for an attribute. I am recursing into each property to do the same for each of their properties. My issue is when I come to some sort of collection property (property that is a collection) or ICollection property. I will not be able to cast the value returned from GetValue into a specific type (tried to cast into IEnumerable but does not work for generic IEnumerables).
Here is some code to help understand a little more:
public class NotificationMessageProcessor<T> : INotificationProcessor<T>
{
IList<string> availableTags = new List<string>();
public string ReplaceNotificationTags<T>(string message, T instance)
{
LoadTagValues(instance);
return ReplaceTags(message);
}
private string ReplaceTags(string message)
{
foreach (KeyValuePair<string, string> tagVal in tagValues)
{
message = message.Replace(string.Format("<{0}>", tagVal.Key), tagVal.Value);
}
return message;
}
private void LoadTagValues(object val)
{
Type elementType = val.GetType();
PropertyInfo[] typeProperties = elementType.GetProperties();
foreach (PropertyInfo prop in typeProperties)
{
NotificationTag[] tags = (NotificationTag[])prop.GetCustomAttributes(typeof(NotificationTag), false);
if (tags != null && tags.Length > 0)
{
string tagName = tags[0].TagName;
object propValue = prop.GetValue(val, null);
string propTypeString = prop.PropertyType.FullName;
tagName = prop.ReflectedType.Name + "." + tagName;
if (propValue != null)
{
tagValues.Add(tagName, propValue.ToString());
}
if (propValue != null)
{
if (!prop.PropertyType.IsPrimitive)
{
LoadTagValues(propValue);
}
}
}
else
{
if (!prop.PropertyType.IsPrimitive)
{
object propValue = null;
if (prop.GetGetMethod().GetParameters().Count() == 0)
{
propValue = prop.GetValue(val, null);
}
else
{
//have a collection...need to process but do not know how many in collection....
propValue = prop.GetValue(val, new object[] { 0 });
}
if (propValue != null)
{
LoadTagValues(propValue);
}
}
}
}
}
NotificationMessageProcessor<User> userProcessor = new NotificationMessageProcessor();
userProcessor.ReplaceNotificationTags<User>(someMessage, instanceOfUser);
The User object has the proper attributes