1
namespace Castle
.MonoRail
.Framework
.Services
3 using System
.Collections
.Generic
;
4 using System
.Reflection
;
11 public class DefaultActionSelector
: IActionSelector
13 private readonly List
<ISubActionSelector
> subSelectors
= new List
<ISubActionSelector
>();
15 #region IActionSelector Members
18 /// Selects the an action.
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
);
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
;
63 return ResolveDefaultMethod(context
.ControllerDescriptor
, controller
, context
, actionType
);
67 /// Registers the specified sub selector.
69 /// <param name="subSelector">The sub selector.</param>
70 public void Register(ISubActionSelector subSelector
)
72 subSelectors
.Add(subSelector
);
76 /// Unregisters the specified sub selector.
78 /// <param name="subSelector">The sub selector.</param>
79 public void Unregister(ISubActionSelector subSelector
)
81 subSelectors
.Remove(subSelector
);
87 /// Selects the action method.
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)
107 return controller
.GetType().GetMethod(name
,
108 BindingFlags
.Public
| BindingFlags
.Instance
|
109 BindingFlags
.IgnoreCase
);
111 AsyncActionPair actionPair
= (AsyncActionPair
) action
;
112 if (actionPair
== null)
116 return actionType
== ActionType
.AsyncBegin
? actionPair
.BeginActionInfo
: actionPair
.EndActionInfo
;
120 /// Runs the sub selectors.
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
);
144 /// The following lines were added to handle _default processing
145 /// if present look for and load _default action method
146 /// <seealso cref="DefaultActionAttribute"/>
148 private IExecutableAction
ResolveDefaultMethod(ControllerMetaDescriptor controllerDesc
, IController controller
,
149 IControllerContext context
, ActionType actionType
)
151 if (controllerDesc
.DefaultAction
!= null)
153 MethodInfo method
= SelectActionMethod(
155 controllerDesc
.DefaultAction
.DefaultAction
, actionType
);
159 ActionMetaDescriptor actionDesc
= controllerDesc
.GetAction(method
);
161 return new ActionMethodExecutor(method
, actionDesc
?? new ActionMetaDescriptor());