<PackageReference Include="Castle.Core" Version="4.0.0-alpha001" />

AttributeUtil

public static class AttributeUtil
using Castle.DynamicProxy.Generators; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; namespace Castle.DynamicProxy.Internal { public static class AttributeUtil { private static readonly IDictionary<Type, IAttributeDisassembler> disassemblers = new Dictionary<Type, IAttributeDisassembler>(); private static IAttributeDisassembler fallbackDisassembler = new AttributeDisassembler(); public static IAttributeDisassembler FallbackDisassembler { get { return fallbackDisassembler; } set { fallbackDisassembler = value; } } public static void AddDisassembler<TAttribute>(IAttributeDisassembler disassembler) where TAttribute : Attribute { if (disassembler == null) throw new ArgumentNullException("disassembler"); disassemblers[typeof(TAttribute)] = disassembler; } public static CustomAttributeBuilder CreateBuilder(CustomAttributeData attribute) { GetArguments(attribute.ConstructorArguments, out Type[] constructorArgTypes, out object[] constructorArgs); ConstructorInfo constructor = TypeExtensions.GetConstructor(attribute.AttributeType, constructorArgTypes); GetSettersAndFields(attribute.AttributeType, attribute.NamedArguments, out PropertyInfo[] properties, out object[] propertyValues, out FieldInfo[] fields, out object[] fieldValues); return new CustomAttributeBuilder(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 (!argument.ArgumentType.GetTypeInfo().get_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.IsField) { list3.Add(TypeExtensions.GetField(attributeType, namedArgument.MemberName)); list4.Add(ReadAttributeValue(namedArgument.TypedValue)); } else { list.Add(TypeExtensions.GetProperty(attributeType, namedArgument.MemberName)); list2.Add(ReadAttributeValue(namedArgument.TypedValue)); } } properties = list.ToArray(); propertyValues = list2.ToArray(); fields = list3.ToArray(); fieldValues = list4.ToArray(); } public static IEnumerable<CustomAttributeBuilder> GetNonInheritableAttributes(this MemberInfo member) { IEnumerable<CustomAttributeData> customAttributes = member.CustomAttributes; foreach (CustomAttributeData item in customAttributes) { Type attributeType = item.AttributeType; if (!ShouldSkipAttributeReplication(attributeType)) { CustomAttributeBuilder builder; try { builder = CreateBuilder(item); } catch (ArgumentException innerException) { throw new ProxyGenerationException(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 TypeInfo) ? "" : ("." + member.Name), typeof(AttributesToAvoidReplicating).FullName), innerException); } if (builder != null) yield return builder; } } } public static IEnumerable<CustomAttributeBuilder> GetNonInheritableAttributes(this ParameterInfo parameter) { IEnumerable<CustomAttributeData> customAttributes = parameter.CustomAttributes; foreach (CustomAttributeData item in customAttributes) { if (!ShouldSkipAttributeReplication(item.AttributeType)) { CustomAttributeBuilder customAttributeBuilder = CreateBuilder(item); if (customAttributeBuilder != null) yield return customAttributeBuilder; } } } private static bool ShouldSkipAttributeReplication(Type attribute) { if (!attribute.GetTypeInfo().get_IsPublic()) return true; if (SpecialCaseAttributThatShouldNotBeReplicated(attribute)) return true; AttributeUsageAttribute[] array = attribute.GetTypeInfo().GetCustomAttributes<AttributeUsageAttribute>(true).ToArray(); if (array.Length != 0) return array[0].Inherited; return true; } private static bool SpecialCaseAttributThatShouldNotBeReplicated(Type attribute) { return AttributesToAvoidReplicating.Contains(attribute); } public static CustomAttributeBuilder CreateBuilder<TAttribute>() where TAttribute : Attribute, new { return new CustomAttributeBuilder(typeof(TAttribute).GetConstructor(Type.EmptyTypes), new object[0]); } public static CustomAttributeBuilder CreateBuilder(Type attribute, object[] constructorArguments) { return new CustomAttributeBuilder(TypeExtensions.GetConstructor(attribute, GetTypes(constructorArguments)), constructorArguments); } internal static CustomAttributeBuilder CreateBuilder(Attribute attribute) { Type type = attribute.GetType(); if (disassemblers.TryGetValue(type, out IAttributeDisassembler value)) return value.Disassemble(attribute); return FallbackDisassembler.Disassemble(attribute); } 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; } } }