PageRenderTime 38ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/FluentNHibernate/Utils/Reflection/ReflectionHelper.cs

https://github.com/Autobase/fluent-nhibernate
C# | 131 lines | 105 code | 26 blank | 0 comment | 23 complexity | 4377f4353b153d22b27353dac2f81335 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. using System.Reflection;
  5. using FluentNHibernate;
  6. namespace FluentNHibernate.Utils.Reflection
  7. {
  8. public static class ReflectionHelper
  9. {
  10. public static Member GetMember<TModel, TReturn>(Expression<Func<TModel, TReturn>> expression)
  11. {
  12. return GetMember(expression.Body);
  13. }
  14. public static Member GetMember<TModel>(Expression<Func<TModel, object>> expression)
  15. {
  16. return GetMember(expression.Body);
  17. }
  18. public static Accessor GetAccessor<MODEL>(Expression<Func<MODEL, object>> expression)
  19. {
  20. MemberExpression memberExpression = GetMemberExpression(expression.Body);
  21. return getAccessor(memberExpression);
  22. }
  23. public static Accessor GetAccessor<MODEL, T>(Expression<Func<MODEL, T>> expression)
  24. {
  25. MemberExpression memberExpression = GetMemberExpression(expression.Body);
  26. return getAccessor(memberExpression);
  27. }
  28. private static bool IsIndexedPropertyAccess(Expression expression)
  29. {
  30. return IsMethodExpression(expression) && expression.ToString().Contains("get_Item");
  31. }
  32. private static bool IsMethodExpression(Expression expression)
  33. {
  34. return expression is MethodCallExpression || (expression is UnaryExpression && IsMethodExpression((expression as UnaryExpression).Operand));
  35. }
  36. private static Member GetMember(Expression expression)
  37. {
  38. if (IsIndexedPropertyAccess(expression))
  39. return GetDynamicComponentProperty(expression).ToMember();
  40. if (IsMethodExpression(expression))
  41. return ((MethodCallExpression)expression).Method.ToMember();
  42. var memberExpression = GetMemberExpression(expression);
  43. return memberExpression.Member.ToMember();
  44. }
  45. private static PropertyInfo GetDynamicComponentProperty(Expression expression)
  46. {
  47. Type desiredConversionType = null;
  48. MethodCallExpression methodCallExpression = null;
  49. var nextOperand = expression;
  50. while (nextOperand != null)
  51. {
  52. if (nextOperand.NodeType == ExpressionType.Call)
  53. {
  54. methodCallExpression = nextOperand as MethodCallExpression;
  55. desiredConversionType = desiredConversionType ?? methodCallExpression.Method.ReturnType;
  56. break;
  57. }
  58. if (nextOperand.NodeType != ExpressionType.Convert)
  59. throw new ArgumentException("Expression not supported", "expression");
  60. var unaryExpression = (UnaryExpression)nextOperand;
  61. desiredConversionType = unaryExpression.Type;
  62. nextOperand = unaryExpression.Operand;
  63. }
  64. var constExpression = methodCallExpression.Arguments[0] as ConstantExpression;
  65. return new DummyPropertyInfo((string)constExpression.Value, desiredConversionType);
  66. }
  67. private static MemberExpression GetMemberExpression(Expression expression)
  68. {
  69. return GetMemberExpression(expression, true);
  70. }
  71. private static MemberExpression GetMemberExpression(Expression expression, bool enforceCheck)
  72. {
  73. MemberExpression memberExpression = null;
  74. if (expression.NodeType == ExpressionType.Convert)
  75. {
  76. var body = (UnaryExpression) expression;
  77. memberExpression = body.Operand as MemberExpression;
  78. }
  79. else if (expression.NodeType == ExpressionType.MemberAccess)
  80. {
  81. memberExpression = expression as MemberExpression;
  82. }
  83. if (enforceCheck && memberExpression == null)
  84. {
  85. throw new ArgumentException("Not a member access", "expression");
  86. }
  87. return memberExpression;
  88. }
  89. private static Accessor getAccessor(MemberExpression memberExpression)
  90. {
  91. var list = new List<Member>();
  92. while (memberExpression != null)
  93. {
  94. list.Add(memberExpression.Member.ToMember());
  95. memberExpression = memberExpression.Expression as MemberExpression;
  96. }
  97. if (list.Count == 1)
  98. {
  99. return new SingleMember(list[0]);
  100. }
  101. list.Reverse();
  102. return new PropertyChain(list.ToArray());
  103. }
  104. }
  105. }