private static ControllerDescriptor GetDescriptor(Type controllerType) { ControllerDescriptor descriptor; if (_controllerDescriptors.TryGetValue(controllerType, out descriptor)) { return descriptor; } descriptor = new ControllerDescriptor(); Type actionResultType = typeof(ActionResult); Type taskActionResultType = typeof(Task<ActionResult>); BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy; MethodInfo[] methods = controllerType.GetMethods(bindingFlags); foreach (MethodInfo method in methods) { ActionDescriptor action = null; if (method.ReturnType.IsAssignableFrom(taskActionResultType)) { action = new ActionDescriptor(method, /* async */ true); } else if (method.ReturnType.IsAssignableFrom(actionResultType)) { action = new ActionDescriptor(method, /* async */ false); } else { continue; } string actionName = method.Name; if (descriptor._actions.ContainsKey(actionName)) { throw new InvalidOperationException(controllerType.Name + " has a duplicate action named " + actionName); } descriptor._actions[actionName] = action; } _controllerDescriptors[controllerType] = descriptor; return descriptor; }