AttributeUtil
using Castle.DynamicProxy.Generators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Castle.DynamicProxy.Internal
{
public static class AttributeUtil
{
public static CustomAttributeInfo CreateInfo(CustomAttributeData attribute)
{
GetArguments(attribute.ConstructorArguments, out Type[] _, out object[] constructorArgs);
ConstructorInfo constructor = attribute.Constructor;
GetSettersAndFields(null, attribute.NamedArguments, out PropertyInfo[] properties, out object[] propertyValues, out FieldInfo[] fields, out object[] fieldValues);
return new CustomAttributeInfo(constructor, constructorArgs, properties, propertyValues, fields, fieldValues);
}
private static void GetArguments(IList<CustomAttributeTypedArgument> constructorArguments, out Type[] constructorArgTypes, out object[] constructorArgs)
{
constructorArgTypes = new Type[constructorArguments.Count];
constructorArgs = new object[constructorArguments.Count];
for (int i = 0; i < constructorArguments.Count; i++) {
constructorArgTypes[i] = constructorArguments[i].ArgumentType;
constructorArgs[i] = ReadAttributeValue(constructorArguments[i]);
}
}
private static object[] GetArguments(IList<CustomAttributeTypedArgument> constructorArguments)
{
object[] array = new object[constructorArguments.Count];
for (int i = 0; i < constructorArguments.Count; i++) {
array[i] = ReadAttributeValue(constructorArguments[i]);
}
return array;
}
private static object ReadAttributeValue(CustomAttributeTypedArgument argument)
{
object value = argument.Value;
if (!System.Reflection.IntrospectionExtensions.GetTypeInfo(argument.ArgumentType).IsArray)
return value;
object[] arguments = GetArguments((IList<CustomAttributeTypedArgument>)value);
object[] array = new object[arguments.Length];
arguments.CopyTo(array, 0);
return array;
}
private static void GetSettersAndFields(Type attributeType, IEnumerable<CustomAttributeNamedArgument> namedArguments, out PropertyInfo[] properties, out object[] propertyValues, out FieldInfo[] fields, out object[] fieldValues)
{
List<PropertyInfo> list = new List<PropertyInfo>();
List<object> list2 = new List<object>();
List<FieldInfo> list3 = new List<FieldInfo>();
List<object> list4 = new List<object>();
foreach (CustomAttributeNamedArgument namedArgument in namedArguments) {
if (namedArgument.MemberInfo.MemberType == MemberTypes.Field) {
list3.Add(namedArgument.MemberInfo as FieldInfo);
list4.Add(ReadAttributeValue(namedArgument.TypedValue));
} else {
list.Add(namedArgument.MemberInfo as PropertyInfo);
list2.Add(ReadAttributeValue(namedArgument.TypedValue));
}
}
properties = list.ToArray();
propertyValues = list2.ToArray();
fields = list3.ToArray();
fieldValues = list4.ToArray();
}
public static IEnumerable<CustomAttributeInfo> GetNonInheritableAttributes(this MemberInfo member)
{
IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(member);
foreach (CustomAttributeData item in attributes) {
Type attributeType = item.Constructor.DeclaringType;
if (!ShouldSkipAttributeReplication(attributeType)) {
CustomAttributeInfo info;
try {
info = CreateInfo(item);
} catch (ArgumentException innerException) {
string message = string.Format("Due to limitations in CLR, DynamicProxy was unable to successfully replicate non-inheritable attribute {0} on {1}{2}. To avoid this error you can chose not to replicate this attribute type by calling '{3}.Add(typeof({0}))'.", attributeType.FullName, member.DeclaringType.FullName, (member is Type) ? "" : ("." + member.Name), typeof(AttributesToAvoidReplicating).FullName);
throw new ProxyGenerationException(message, innerException);
}
if (info != null)
yield return info;
}
}
}
public static IEnumerable<CustomAttributeInfo> GetNonInheritableAttributes(this ParameterInfo parameter)
{
IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(parameter);
foreach (CustomAttributeData item in attributes) {
Type attributeType = item.Constructor.DeclaringType;
if (!ShouldSkipAttributeReplication(attributeType)) {
CustomAttributeInfo info = CreateInfo(item);
if (info != null)
yield return info;
}
}
}
private static bool ShouldSkipAttributeReplication(Type attribute)
{
if (!System.Reflection.IntrospectionExtensions.GetTypeInfo(attribute).IsPublic)
return true;
if (SpecialCaseAttributeThatShouldNotBeReplicated(attribute))
return true;
AttributeUsageAttribute[] array = System.Reflection.CustomAttributeExtensions.GetCustomAttributes<AttributeUsageAttribute>(System.Reflection.IntrospectionExtensions.GetTypeInfo(attribute), true).ToArray();
if (array.Length != 0)
return array[0].Inherited;
return true;
}
private static bool SpecialCaseAttributeThatShouldNotBeReplicated(Type attribute)
{
return AttributesToAvoidReplicating.ShouldAvoid(attribute);
}
public static CustomAttributeInfo CreateInfo<TAttribute>() where TAttribute : Attribute, new
{
ConstructorInfo constructor = typeof(TAttribute).GetConstructor(Type.EmptyTypes);
return new CustomAttributeInfo(constructor, new object[0]);
}
public static CustomAttributeInfo CreateInfo(Type attribute, object[] constructorArguments)
{
ConstructorInfo constructor = attribute.GetConstructor(GetTypes(constructorArguments));
return new CustomAttributeInfo(constructor, constructorArguments);
}
private static Type[] GetTypes(object[] objects)
{
Type[] array = new Type[objects.Length];
for (int i = 0; i < array.Length; i++) {
array[i] = objects[i].GetType();
}
return array;
}
}
}