PageRenderTime 67ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ObjectComparer/Source/Configuration/MetadataReaderReflectDescriptions.cs

#
C# | 184 lines | 145 code | 33 blank | 6 comment | 47 complexity | 6695341ac2a1205290b7046053920594 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using System.Diagnostics;
  5. using System.Collections;
  6. namespace SIT.Components.ObjectComparer {
  7. public class MetadataReaderReflectDescriptions : MetadataReader {
  8. public MetadataReaderReflectDescriptions(IContext context) : base(context) { }
  9. public override ClassDescription GetClassDescription(object value) {
  10. throw new NotImplementedException();
  11. }
  12. public override MemberDescription GetPropertyDescription(object value, MemberInfo pi) {
  13. throw new NotImplementedException();
  14. }
  15. public override ItemDescription GetDescription(object item, MemberInfo pi) {
  16. throw new NotImplementedException();
  17. }
  18. public override List<MemberInfo> GetMembers(object value) {
  19. var retval = new List<MemberInfo>();
  20. if (value == null)
  21. return retval;
  22. var t = value.GetType();
  23. if (t.IsPrimitive)
  24. return retval;
  25. var typeName = t.FullName;
  26. var classDescription = _context.Configuration.ClassDescriptions.Find(x => string.Equals(x.FullName, typeName));
  27. if (classDescription == null)
  28. return retval;
  29. //throw new ArgumentException(string.Format("Did not found a class description for type '{0}'", typeName));
  30. classDescription.Properties.ForEach(x => {
  31. if (x.MemberInfo == null) {
  32. var members = t.GetMember(x.FullName, _context.Configuration.GetMemberBindingFlags);
  33. x.MemberInfo = members[0];
  34. }
  35. retval.Add(x.MemberInfo);
  36. });
  37. return retval;
  38. }
  39. private ClassDescription FindClassDescription(System.Type type) {
  40. var retval = _context.Configuration.ClassDescriptions.Find(x => string.Equals(x.FullName, type.FullName));
  41. if (!_context.Configuration.AutoPopuplateDerived)
  42. return retval;
  43. var interfaceTypes = type.GetInterfaces();
  44. foreach (var cd in _context.Configuration.ClassDescriptions) {
  45. var ifType = Array.Find(interfaceTypes, x => string.Equals(x.FullName, cd.FullName));
  46. if (ifType != null) {
  47. var derivedCd = DeepCopy.Copy<ClassDescription>(cd);
  48. derivedCd.FullName = ifType.FullName;
  49. _context.Configuration.ClassDescriptions.Add(derivedCd);
  50. retval = derivedCd;
  51. }
  52. }
  53. return retval;
  54. }
  55. public override void UpdateSnapshotData(SnapshotData data, object value, MemberInfo mi) {
  56. if (mi != null) {
  57. var memberName = mi.Name;
  58. var declaringTypeName = mi.DeclaringType.FullName;
  59. //var cd = FindClassDescription(mi.DeclaringType);
  60. //var md = cd.Properties.Find(x => string.Equals(x.FullName, memberName));
  61. var md = _context.Configuration.ClassDescriptions.Find(x => string.Equals(x.FullName, declaringTypeName)).Properties.Find(x => string.Equals(x.FullName, memberName));
  62. data.Name = md.DisplayName;
  63. data.TypeName = md.FullName;
  64. data.Value = null;
  65. } else {
  66. if (value != null) {
  67. var t = value.GetType();
  68. var cd = _context.Configuration.ClassDescriptions.Find(x => string.Equals(x.FullName, t.FullName));
  69. if (cd == null) {
  70. var ifTypes = t.GetInterfaces();
  71. foreach (var ifType in ifTypes) {
  72. cd = _context.Configuration.ClassDescriptions.Find(x => {
  73. if (x.FullName == ifType.FullName)
  74. return true;
  75. object convertedValue = null;
  76. try {
  77. var destType = System.Type.GetType(x.FullName);
  78. convertedValue = Convert.ChangeType(value, destType);
  79. } catch { }
  80. if (convertedValue != null)
  81. return true;
  82. return false;
  83. });
  84. if (cd != null)
  85. break;
  86. }
  87. if (t.IsGenericType) {
  88. foreach (var ifType in ifTypes) {
  89. if (!ifType.IsGenericType)
  90. continue;
  91. if (ifType.GetGenericTypeDefinition() != typeof(IEnumerable<>))
  92. continue;
  93. var genericArgType = ifType.GetGenericArguments()[0];
  94. if (_context.Configuration.ClassDescriptions.Exists(x => x.FullName == genericArgType.FullName))
  95. continue;
  96. System.Type typeToAdd = null;
  97. typeToAdd = genericArgType.IsGenericType ?
  98. genericArgType.GetGenericTypeDefinition() :
  99. genericArgType;
  100. var derivedCd = _context.Configuration.ClassDescriptions.Find(x => x.FullName == typeToAdd.FullName);
  101. if (derivedCd == null) {
  102. if (cd.FullName == typeof(IDictionary).FullName && typeToAdd == typeof(KeyValuePair<,>)) {
  103. var tmpDictItemCd = _context.Configuration.ClassDescriptions.Find(x => x.FullName == typeof(DictionaryEntry).FullName);
  104. if (tmpDictItemCd != null) {
  105. derivedCd = new ClassDescription() {
  106. DisplayName = tmpDictItemCd.DisplayName,
  107. FullName = genericArgType.FullName,
  108. IsDerived = true,
  109. IdPropertyName = tmpDictItemCd.IdPropertyName
  110. };
  111. derivedCd.Properties.AddRange(
  112. tmpDictItemCd.Properties.ConvertAll(old=>
  113. new MemberDescription(derivedCd){
  114. DisplayName = old.DisplayName,
  115. FullName=old.FullName,
  116. HasIndexParameters=old.HasIndexParameters,
  117. MemberInfo = genericArgType.GetMember(old.MemberInfo.Name)[0],
  118. Name=old.Name,
  119. TypeIsEnumerable=old.TypeIsEnumerable,
  120. TypeIsString=old.TypeIsString,
  121. TypeName=old.TypeName
  122. }
  123. )
  124. );
  125. }
  126. } else {
  127. Console.WriteLine("Resolve");
  128. //throw new TypeLoadException(string.Format("Cannot find type in config: {0}", t.FullName));
  129. }
  130. }
  131. if (derivedCd != null)
  132. _context.Configuration.ClassDescriptions.Add(derivedCd);
  133. }
  134. }
  135. }
  136. if (cd != null) {
  137. data.TypeName = cd.FullName;
  138. data.Name = cd.DisplayName;
  139. data.IdPropertyName = cd.IdPropertyName;
  140. }
  141. }
  142. }
  143. if (value == null)
  144. return;
  145. //if (value.GetType().IsValueType | value is string)
  146. // return;
  147. if (value.GetType().IsValueType | value is string)
  148. data.Value = value;
  149. }
  150. }
  151. }