Magellan Controllers
Back to: Magellan Home
As an MVC framework, controllers are the most prominent object in Magellan. At their simplest, controllers are implemented as classes, and actions are implemented as methods on the class. Actions on a controller must be public methods, and must return ActionResult
objects. Here is an example:
public class CustomerController : Controller
{
public ActionResult Index()
{
Model = Customers.GetAll();
return Page();
}
public ActionResult Show(int customerId)
{
Model = Customers.Get(customerId);
return Page();
}
}
This page describes how controllers are executed.
Controller Factories
Navigation begins at the Navigator, either by using a command, behavior or calling it explicitly. The Navigator processes the request by resolving a controller from the controller factory, executing the request, and releasing the controller back to the factory:
public void Navigate(NavigationRequest request)
{
Guard.ArgumentNotNull(request, "request");
var controllerFactory = ControllerBuilder.Current.GetControllerFactory();
var controllerResult = controllerFactory.CreateController(request, request.Controller);
var controller = controllerResult.Controller;
var context = new ControllerContext(controller, request, controllerResult.Release);
controller.Execute(context);
}
The controller factory implements the IControllerFactory
interface, and provides a method to resolve the controller:
public interface IControllerFactory
{
ControllerFactoryResult CreateController(NavigationRequest request, string controllerName);
}
The controller factory is set via the ControllerBuilder.Current.SetControllerFactory
method. See the topic on using an IOC container for an example on creating your own controller factory.
Controllers
The controllers returned by the controller factory must implement the IController
interface, which is quite simple:
public interface IController
{
void Execute(NavigationRequest request);
}
The NavigationRequest
passed to the controller contains information about the controller name, action name, and any parameters for the request. It is up to the controller to decide how to handle the request given this information. If the class/method convention used by Magellan isn't enough, your controller can use different mechanisms to prosecute the request. Magellan's navigator, behaviors, and commands can still be used.
Controllers will usually derive from the Controller
base class. When this controller executes a request, it will work with an action invoker to resolve the action, call any action filters, execute the action, and evaluate the result.
The Execute method on the Controller base class is quite simple:
public void Execute(NavigationRequest request)
{
Request = request;
ActionInvoker.ExecuteAction(ControllerContext, request.Action, ModelBinders);
}
To make writing controllers easy, a number of helper methods exist for creating the action results, such as View()
, Cancel()
and Redirect()
. You can read more about them in the action results section.
Action Invoker
The action invoker is used by the controller to handle the details of executing the action. This allows you to continue to derive from the Controller
class while executing actions in a very different way. By default, the controller's ActionInvoker
property is set to the DefaultActionInvoker
.
The default action invoker uses reflection to map the requests Action property to a method on the controller. It then performs the following steps:
- Executes all pre-action filters
- Executes the action
- Executes all post-action filters
- Executes the action result
Action filters provide a way for you to implement cross-cutting concerns on controllers, such as authorization, logging, state management, and other examples.
When the action has been executed, it will return an Action Result. This is an important point - controllers do not show views directly, they simply return an object which is responsible for resolving and showing the view. This allows you handle the navigation request in a very different way without altering controllers.
Model Binders
One of the tasks the action invoker takes care of is mapping parameters from the current NavigationRequest
to arguments passed to the action method on the controller. Rather than putting this logic in the action invoker, it instead calls through to objects known as Model Binders
.
The ModelBinders.Binders
static property is a registry of active model binders, associated with a type. By default there is only one binder - a DefaultModelBinder
which uses type descriptors and casting to perform the conversion. If you wish to customize how request parameters are mapped to action method parameters, you can do so through implementing the IModelBinder
interface and registering it with the ModelBinders.Binders
collection.
See also:
Back to: Magellan Home