in src/WebJobs.Script/Binding/ExtensionBinding.cs [138:213]
internal static AttributeBuilderInfo GetAttributeBuilderInfo(Attribute attribute)
{
IDictionary<string, object> attributeData = GetAttributeData(attribute);
Dictionary<string, object> attributeDataCaseInsensitive = new Dictionary<string, object>(attributeData, StringComparer.OrdinalIgnoreCase);
Type attributeType = attribute.GetType();
// Pick the ctor with the longest parameter list where all parameters are matched.
int longestMatch = -1;
ConstructorInfo bestCtor = null;
Dictionary<PropertyInfo, object> propertiesToSet = null;
object[] constructorArgs = null;
var ctors = attributeType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
foreach (var currCtor in ctors)
{
var currCtorParams = currCtor.GetParameters();
int len = currCtorParams.Length;
object[] currConstructorArgs = new object[len];
bool hasAllParameters = true;
for (int i = 0; i < len; i++)
{
var p = currCtorParams[i];
object value = null;
if (!attributeDataCaseInsensitive.TryGetValue(p.Name, out value) || value == null)
{
hasAllParameters = false;
break;
}
currConstructorArgs[i] = value;
}
if (hasAllParameters)
{
if (len > longestMatch)
{
propertiesToSet = new Dictionary<PropertyInfo, object>();
// Set any remaining property values
foreach (var prop in attributeType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (!prop.CanWrite || !prop.GetSetMethod(/*nonPublic*/ true).IsPublic ||
Nullable.GetUnderlyingType(prop.PropertyType) != null)
{
continue;
}
object objValue = null;
if (attributeDataCaseInsensitive.TryGetValue(prop.Name, out objValue))
{
propertiesToSet.Add(prop, objValue);
}
}
bestCtor = currCtor;
constructorArgs = currConstructorArgs;
longestMatch = len;
}
}
}
if (bestCtor == null)
{
// error!!!
throw new InvalidOperationException("Can't figure out which ctor to call.");
}
AttributeBuilderInfo info = new AttributeBuilderInfo
{
Constructor = bestCtor,
ConstructorArgs = constructorArgs,
Properties = propertiesToSet
};
return info;
}