private IReflectionValueDescriptor CreateDescriptor(IReflectionStateMember member, object value, Type runtimeMemberType) { Type descriptorType; Type memberType = member.MemberType; if (memberType.IsEnum) { descriptorType = typeof(ReflectionEnumValueDescriptor <, ,>) .MakeGenericType(memberType, runtimeMemberType, memberType.GetEnumUnderlyingType()); } else { descriptorType = typeof(ReflectionValueDescriptor <,>) .MakeGenericType(memberType, runtimeMemberType); } IReflectionValueDescriptor descriptor = (IReflectionValueDescriptor)Activator.CreateInstance (descriptorType, _processor, _stateMemberProvider, member, value); return(descriptor); }
private void CallGenericMethod(IReflectionValueDescriptor descriptor, Type processorType, Type genericType, string methodName) { MethodInfo methodToCall = processorType.GetMethod(methodName) .MakeGenericMethod(genericType); methodToCall.Invoke(_processor, new object[] { descriptor }); }
private void VisitMember(IReflectionStateMember member, object owner, Type runtimeMemberType, bool skipSpecialMethod, bool routed) { IReflectionValueDescriptor descriptor = CreateDescriptor(member, owner, runtimeMemberType); CallProcess(descriptor, skipSpecialMethod, routed); }
private void CallProcess(IReflectionValueDescriptor descriptor, bool skipSpecialMethod, bool routed) { Type fieldType = descriptor.StateMember.MemberType; bool methodCalled = false; if (!fieldType.IsValueType && !skipSpecialMethod) { methodCalled = TryCallSpecialMethod(descriptor, fieldType); } if (!methodCalled) { CallMatchedProcess(descriptor, routed); } }
private bool TryCallSpecialMethod(IReflectionValueDescriptor descriptor, Type fieldType) { object value = descriptor.Get(); INullProcessor processor = _processor as INullProcessor; IRevisitedProcessor revisitedProcessor = _processor as IRevisitedProcessor; if (processor != null && value == null) { CallGenericMethod(descriptor, typeof(INullProcessor), fieldType, "ProcessNull"); return(true); } else if ((value != null) && (revisitedProcessor != null) && revisitedProcessor.Visited(value)) { CallGenericMethod(descriptor, typeof(IRevisitedProcessor), fieldType, "ProcessRevisited"); return(true); } return(false); }
private void CallMatchedProcess(IReflectionValueDescriptor descriptor, bool routed) { GenericArgumentBinder binder = new GenericArgumentBinder(new FallbackToFirstCandidateMethodSelector(new BinderMethodSelector(Type.DefaultBinder))); IEnumerable <MethodInfo> methods = _processor.GetType().GetMethods() .Where(x => x.IsDefined(typeof(ProcessorMethodAttribute))) .Where(x => !x.GetCustomAttribute <ProcessorMethodAttribute>().OnlyOnRoute || routed); Type descriptorType = descriptor.GetType(); IEnumerable <IGrouping <int, MethodInfo> > candidates = methods.Select(method => Bind(binder, method, descriptorType)) .Where(x => x != null) .GroupBy(x => x.GetCustomAttribute <ProcessorMethodAttribute>().Precedence) .OrderBy(x => x.Key); IGrouping <int, MethodInfo> maximum = candidates.FirstOrDefault(); if (maximum.Skip(1).Any()) { throw new Exception("Too many candidates for the processor thingy. Use precedence."); } else { MethodInfo method = maximum.FirstOrDefault(); if (method != null) { method.Invoke(_processor, new object[] { descriptor }); } else { throw new Exception( "No method found :(, this might be a bug in your code, or in the GraphClimber. Good luck."); } } }