using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Abp.Reflection { /// /// Defines helper methods for reflection. /// internal static class ReflectionHelper { /// /// Checks whether implements/inherits . /// /// Type to check /// Generic type public static bool IsAssignableToGenericType(Type givenType, Type genericType) { var givenTypeInfo = givenType.GetTypeInfo(); if (givenTypeInfo.IsGenericType && givenType.GetGenericTypeDefinition() == genericType) { return true; } foreach (var interfaceType in givenType.GetInterfaces()) { if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == genericType) { return true; } } if (givenTypeInfo.BaseType == null) { return false; } return IsAssignableToGenericType(givenTypeInfo.BaseType, genericType); } /// /// Gets a list of attributes defined for a class member and it's declaring type including inherited attributes. /// /// Inherit attribute from base classes /// MemberInfo public static List GetAttributesOfMemberAndDeclaringType(MemberInfo memberInfo, bool inherit = true) { var attributeList = new List(); attributeList.AddRange(memberInfo.GetCustomAttributes(inherit)); if (memberInfo.DeclaringType != null) { attributeList.AddRange(memberInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(inherit)); } return attributeList; } /// /// Gets a list of attributes defined for a class member and type including inherited attributes. /// /// MemberInfo /// Type /// Inherit attribute from base classes public static List GetAttributesOfMemberAndType(MemberInfo memberInfo, Type type, bool inherit = true) { var attributeList = new List(); attributeList.AddRange(memberInfo.GetCustomAttributes(inherit)); attributeList.AddRange(type.GetTypeInfo().GetCustomAttributes(inherit)); return attributeList; } /// /// Gets a list of attributes defined for a class member and it's declaring type including inherited attributes. /// /// Type of the attribute /// MemberInfo /// Inherit attribute from base classes public static List GetAttributesOfMemberAndDeclaringType(MemberInfo memberInfo, bool inherit = true) where TAttribute : Attribute { var attributeList = new List(); if (memberInfo.IsDefined(typeof(TAttribute), inherit)) { attributeList.AddRange(memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast()); } if (memberInfo.DeclaringType != null && memberInfo.DeclaringType.GetTypeInfo().IsDefined(typeof(TAttribute), inherit)) { attributeList.AddRange(memberInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(typeof(TAttribute), inherit).Cast()); } return attributeList; } /// /// Gets a list of attributes defined for a class member and type including inherited attributes. /// /// Type of the attribute /// MemberInfo /// Type /// Inherit attribute from base classes public static List GetAttributesOfMemberAndType(MemberInfo memberInfo, Type type, bool inherit = true) where TAttribute : Attribute { var attributeList = new List(); if (memberInfo.IsDefined(typeof(TAttribute), inherit)) { attributeList.AddRange(memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast()); } if (type.GetTypeInfo().IsDefined(typeof(TAttribute), inherit)) { attributeList.AddRange(type.GetTypeInfo().GetCustomAttributes(typeof(TAttribute), inherit).Cast()); } return attributeList; } /// /// Tries to gets an of attribute defined for a class member and it's declaring type including inherited attributes. /// Returns default value if it's not declared at all. /// /// Type of the attribute /// MemberInfo /// Default value (null as default) /// Inherit attribute from base classes public static TAttribute GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(MemberInfo memberInfo, TAttribute defaultValue = default(TAttribute), bool inherit = true) where TAttribute : class { return memberInfo.GetCustomAttributes(true).OfType().FirstOrDefault() ?? memberInfo.ReflectedType?.GetTypeInfo().GetCustomAttributes(true).OfType().FirstOrDefault() ?? defaultValue; } /// /// Tries to gets an of attribute defined for a class member and it's declaring type including inherited attributes. /// Returns default value if it's not declared at all. /// /// Type of the attribute /// MemberInfo /// Default value (null as default) /// Inherit attribute from base classes public static TAttribute GetSingleAttributeOrDefault(MemberInfo memberInfo, TAttribute defaultValue = default(TAttribute), bool inherit = true) where TAttribute : Attribute { //Get attribute on the member if (memberInfo.IsDefined(typeof(TAttribute), inherit)) { return memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast().First(); } return defaultValue; } /// /// Gets a property by it's full path from given object /// /// Object to get value from /// Type of given object /// Full path of property /// internal static object GetPropertyByPath(object obj, Type objectType, string propertyPath) { var property = obj; var currentType = objectType; var objectPath = currentType.FullName; var absolutePropertyPath = propertyPath; if (absolutePropertyPath.StartsWith(objectPath)) { absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", ""); } foreach (var propertyName in absolutePropertyPath.Split('.')) { property = currentType.GetProperty(propertyName); currentType = ((PropertyInfo) property).PropertyType; } return property; } /// /// Gets value of a property by it's full path from given object /// /// Object to get value from /// Type of given object /// Full path of property /// internal static object GetValueByPath(object obj, Type objectType, string propertyPath) { var value = obj; var currentType = objectType; var objectPath = currentType.FullName; var absolutePropertyPath = propertyPath; if (absolutePropertyPath.StartsWith(objectPath)) { absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", ""); } foreach (var propertyName in absolutePropertyPath.Split('.')) { var property = currentType.GetProperty(propertyName); value = property.GetValue(value, null); currentType = property.PropertyType; } return value; } /// /// Sets value of a property by it's full path on given object /// /// /// /// /// internal static void SetValueByPath(object obj, Type objectType, string propertyPath, object value) { var currentType = objectType; PropertyInfo property; var objectPath = currentType.FullName; var absolutePropertyPath = propertyPath; if (absolutePropertyPath.StartsWith(objectPath)) { absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", ""); } var properties = absolutePropertyPath.Split('.'); if (properties.Length == 1) { property = objectType.GetProperty(properties.First()); property.SetValue(obj, value); return; } for (int i = 0; i < properties.Length - 1; i++) { property = currentType.GetProperty(properties[i]); obj = property.GetValue(obj, null); currentType = property.PropertyType; } property = currentType.GetProperty(properties.Last()); property.SetValue(obj, value); } internal static bool IsPropertyGetterSetterMethod(MethodInfo method, Type type) { if (!method.IsSpecialName) { return false; } if (method.Name.Length < 5) { return false; } return type.GetProperty(method.Name.Substring(4), BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic) != null; } } }