Fixing an issue with output parameters that are of type IntPtr
[castle.git] / MonoRail / Castle.MonoRail.Framework / Services / DefaultActionSelector.cs
blob2f5b3fdbad1a3789f37093bf622c23bc78b55cd3
1 namespace Castle.MonoRail.Framework.Services
3 using System.Collections.Generic;
4 using System.Reflection;
5 using Descriptors;
6 using Providers;
8 /// <summary>
9 /// Pendent
10 /// </summary>
11 public class DefaultActionSelector : IActionSelector
13 private readonly List<ISubActionSelector> subSelectors = new List<ISubActionSelector>();
15 #region IActionSelector Members
17 /// <summary>
18 /// Selects the an action.
19 /// </summary>
20 /// <param name="engineContext">The engine context.</param>
21 /// <param name="controller">The controller.</param>
22 /// <param name="context">The context.</param>
23 /// <param name="actionType">Type of the action.</param>
24 /// <returns></returns>
25 public IExecutableAction Select(IEngineContext engineContext, IController controller, IControllerContext context,
26 ActionType actionType)
28 string actionName = context.Action;
30 // Look for the target method
31 MethodInfo actionMethod = SelectActionMethod(controller, context, context.Action, actionType);
33 if (actionMethod == null)
35 // If we couldn't find a method for this action, look for a dynamic action
36 IDynamicAction dynAction = null;
38 if (context.DynamicActions.ContainsKey(actionName))
40 dynAction = context.DynamicActions[actionName];
43 if (dynAction != null)
45 return new DynamicActionExecutor(dynAction);
48 else
50 ActionMetaDescriptor actionDesc = context.ControllerDescriptor.GetAction(actionMethod);
52 return new ActionMethodExecutor(actionMethod, actionDesc ?? new ActionMetaDescriptor());
55 IExecutableAction executableAction = RunSubSelectors(engineContext, controller, context, actionType);
57 if (executableAction != null)
59 return executableAction;
62 // Last try:
63 return ResolveDefaultMethod(context.ControllerDescriptor, controller, context, actionType);
66 /// <summary>
67 /// Registers the specified sub selector.
68 /// </summary>
69 /// <param name="subSelector">The sub selector.</param>
70 public void Register(ISubActionSelector subSelector)
72 subSelectors.Add(subSelector);
75 /// <summary>
76 /// Unregisters the specified sub selector.
77 /// </summary>
78 /// <param name="subSelector">The sub selector.</param>
79 public void Unregister(ISubActionSelector subSelector)
81 subSelectors.Remove(subSelector);
84 #endregion
86 /// <summary>
87 /// Selects the action method.
88 /// </summary>
89 /// <param name="controller">The controller.</param>
90 /// <param name="context">The context.</param>
91 /// <param name="name">The name.</param>
92 /// <param name="actionType">The action type</param>
93 /// <returns></returns>
94 protected virtual MethodInfo SelectActionMethod(IController controller, IControllerContext context, string name,
95 ActionType actionType)
97 object action = context.ControllerDescriptor.Actions[name];
98 if (actionType == ActionType.Sync)
100 MethodInfo methodInfo = action as MethodInfo;
102 if (methodInfo != null)
104 return methodInfo;
107 return controller.GetType().GetMethod(name,
108 BindingFlags.Public | BindingFlags.Instance |
109 BindingFlags.IgnoreCase);
111 AsyncActionPair actionPair = (AsyncActionPair) action;
112 if (actionPair == null)
114 return null;
116 return actionType == ActionType.AsyncBegin ? actionPair.BeginActionInfo : actionPair.EndActionInfo;
119 /// <summary>
120 /// Runs the sub selectors.
121 /// </summary>
122 /// <param name="engineContext">The engine context.</param>
123 /// <param name="controller">The controller.</param>
124 /// <param name="context">The context.</param>
125 /// <param name="actionType">Type of the action.</param>
126 /// <returns></returns>
127 protected virtual IExecutableAction RunSubSelectors(IEngineContext engineContext, IController controller,
128 IControllerContext context, ActionType actionType)
130 foreach(ISubActionSelector selector in subSelectors)
132 IExecutableAction action = selector.Select(engineContext, controller, context, actionType);
134 if (action != null)
136 return action;
140 return null;
143 /// <summary>
144 /// The following lines were added to handle _default processing
145 /// if present look for and load _default action method
146 /// <seealso cref="DefaultActionAttribute"/>
147 /// </summary>
148 private IExecutableAction ResolveDefaultMethod(ControllerMetaDescriptor controllerDesc, IController controller,
149 IControllerContext context, ActionType actionType)
151 if (controllerDesc.DefaultAction != null)
153 MethodInfo method = SelectActionMethod(
154 controller, context,
155 controllerDesc.DefaultAction.DefaultAction, actionType);
157 if (method != null)
159 ActionMetaDescriptor actionDesc = controllerDesc.GetAction(method);
161 return new ActionMethodExecutor(method, actionDesc ?? new ActionMetaDescriptor());
165 return null;