static CustomAttributeBuilder BuildCustomAttribute(object customAttribute)
{
ConstructorInfo longestCtor = null;
// Get constructor with the largest number of parameters
foreach (var cInfo in customAttribute.GetType().GetConstructors().
Where(cInfo => longestCtor == null || longestCtor.GetParameters().Length < cInfo.GetParameters().Length))
{
longestCtor = cInfo;
}
if (longestCtor == null)
{
return null;
}
// For each constructor parameter, get corresponding (by name similarity) property and get its value
var args = new object[longestCtor.GetParameters().Length];
var position = 0;
foreach (var consParamInfo in longestCtor.GetParameters())
{
var attrPropInfo = customAttribute.GetType().GetProperty(consParamInfo.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (attrPropInfo != null)
{
args[position] = attrPropInfo.GetValue(customAttribute, null);
}
else
{
args[position] = null;
var attrFieldInfo = customAttribute.GetType().GetField(consParamInfo.Name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (attrFieldInfo == null)
{
if (consParamInfo.ParameterType.IsValueType)
{
args[position] = Activator.CreateInstance(consParamInfo.ParameterType);
}
}
else
{
args[position] = attrFieldInfo.GetValue(customAttribute);
}
}
++position;
}
var propList = new List<PropertyInfo>();
var propValueList = new List<object>();
foreach (var attrPropInfo in customAttribute.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!attrPropInfo.CanWrite)
{
continue;
}
object defaultValue = null;
var defaultAttributes = attrPropInfo.GetCustomAttributes(typeof(DefaultValueAttribute), true);
if (defaultAttributes.Length > 0)
{
defaultValue = ((DefaultValueAttribute) defaultAttributes[0]).Value;
}
var value = attrPropInfo.GetValue(customAttribute, null);
if (value == defaultValue)
{
continue;
}
propList.Add(attrPropInfo);
propValueList.Add(value);
}
return new CustomAttributeBuilder(longestCtor, args, propList.ToArray(), propValueList.ToArray());
}