public DescriptorVariable(IClimbStore store, Expression processor, Expression owner, IStateMember member, Type runtimeType) { Type descriptorType = DescriptorExtensions.GetDescriptorType(member, runtimeType); Type memberLocalType = typeof(MemberLocal <,>).MakeGenericType(member.MemberType, runtimeType); _reference = Expression.Variable(descriptorType, member.Name.FirstLowerCase() + "Descriptor"); object memberLocal = Activator.CreateInstance(memberLocalType, store, member); ConstructorInfo constructor = descriptorType.GetConstructors().FirstOrDefault(); ParameterInfo ownerParameter = constructor.GetParameters()[1]; Type ownerParameterType = ownerParameter.ParameterType; NewExpression creation = Expression.New(constructor, processor, owner.Convert(ownerParameterType), memberLocal.Constant(), store.Constant()); BinaryExpression assign = Expression.Assign(_reference, creation); _descriptorDeclaration = assign; }
public MethodInfo GetMethod(Type processorType, IStateMember member, Type runtimeType, bool routed) { Type descriptorType = DescriptorExtensions.GetDescriptorType(member, runtimeType); // TODO: First implementation: reimplement this. GenericArgumentBinder binder = new GenericArgumentBinder (new FallbackToFirstCandidateMethodSelector (new BinderMethodSelector(Type.DefaultBinder))); // TODO: Return this after processors are fixed. // IEnumerable<Type> typesToSearch = processorType.WithInterfaces(); IEnumerable <Type> typesToSearch = processorType.AsEnumerable(); IEnumerable <MethodInfo> methods = typesToSearch.SelectMany(x => x.GetMethods()) .Where(x => x.IsDefined(typeof(ProcessorMethodAttribute))) .Where(x => !x.GetCustomAttribute <ProcessorMethodAttribute>().OnlyOnRoute || routed); 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(); return(method); } }