AttributeUtil
using Castle.DynamicProxy.Generators;
using System;
using System.Collections.Generic;
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 IEnumerable<CustomAttributeBuilder> GetNonInheritableAttributes(this MemberInfo member)
{
object[] attributes = member.GetCustomAttributes(false);
try {
object[] array = attributes;
foreach (object attribute in array) {
Type attributeType = attribute.GetType();
if (!ShouldSkipAttributeReplication(attributeType)) {
CustomAttributeBuilder builder;
try {
builder = CreateBuilder(attribute as Attribute);
} 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, ((object)member.ReflectedType == null) ? "" : member.ReflectedType.FullName, (member is Type) ? "" : ("." + member.Name), typeof(AttributesToAvoidReplicating).FullName);
throw new ProxyGenerationException(message, innerException);
}
if (builder != null)
yield return builder;
}
}
} finally {
}
}
public static IEnumerable<CustomAttributeBuilder> GetNonInheritableAttributes(this ParameterInfo parameter)
{
object[] attributes = parameter.GetCustomAttributes(false);
try {
object[] array = attributes;
foreach (object attribute in array) {
Type attributeType = attribute.GetType();
if (!ShouldSkipAttributeReplication(attributeType)) {
CustomAttributeBuilder builder = CreateBuilder(attribute as Attribute);
if (builder != null)
yield return builder;
}
}
} finally {
}
}
private static bool ShouldSkipAttributeReplication(Type attribute)
{
if (!attribute.IsPublic)
return true;
if (SpecialCaseAttributThatShouldNotBeReplicated(attribute))
return true;
object[] customAttributes = attribute.GetCustomAttributes(typeof(AttributeUsageAttribute), true);
if (customAttributes.Length != 0) {
AttributeUsageAttribute attributeUsageAttribute = (AttributeUsageAttribute)customAttributes[0];
return attributeUsageAttribute.Inherited;
}
return true;
}
private static bool SpecialCaseAttributThatShouldNotBeReplicated(Type attribute)
{
return AttributesToAvoidReplicating.Contains(attribute);
}
public static CustomAttributeBuilder CreateBuilder<TAttribute>() where TAttribute : Attribute, new
{
ConstructorInfo constructor = typeof(TAttribute).GetConstructor(Type.EmptyTypes);
return new CustomAttributeBuilder(constructor, new object[0]);
}
public static CustomAttributeBuilder CreateBuilder(Type attribute, object[] constructorArguments)
{
ConstructorInfo constructor = attribute.GetConstructor(GetTypes(constructorArguments));
return new CustomAttributeBuilder(constructor, 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;
}
}
}