We put points in the MVC Framework. Controller factory

    This chapter puts an end to the answer to the question “How and why does the controller factory work?”.

    imageThis is the third article in a series of articles about the internal structure of the MVC Framework . Summary of previous parts: Do I need to upgrade to the MVC Framework? ; mechanism of operation of the MVC Framework: Part 1 and Part 2 . In this article, we will talk about the mechanism of the controller factory, an important part of the MVC Framework, with which the whole framework begins to work.

    Why “factory”?


    Factory is the name of a design pattern that defines the mechanism for creating objects (instances of classes) without specifying the classes themselves. See the wiki for more details . In the MVC Framework, the controller factory, as the name implies, is designed to create controller objects. Since the information about the required controller comes from the ASP.NET routing mechanism in the form of a string with the class name, the controller factory builds controller objects based on this string.

    Controller factory


    Typically, a factory creates objects of classes defined by an interface. For the MVC Framework controller factory, this interface is IController . In general, the definition of the controller factory interface looks like this:
    public interface IControllerFactory {
      IController CreateController(RequestContext requestContext, string controllerName);
      void ReleaseController(IController controller);
    }

    * This source code was highlighted with Source Code Highlighter.

    A very simple interface: the CreateController method should return objects implementing the IController, ReleaseController should take care of removing the controller when the controller ceases to exist.

    In order for the controller factory to return the necessary controller instance, parameters are passed to it in the form of the name of the controller controllerName and the request context requestContext , which forms the ASP.NET routing mechanism. The ASP.NET MVC Framework developer does not need to write his own implementation of the controller factory, since the framework contains the default implementation of the factory. This implementation is the DefaultControllerFactory class .

    DefaultControllerFactory


    When the ASP.NET MVC Framework engine receives a user request, the associated MvcRouteHandler handler processes it. Having found a suitable route, MvcRouteHandler calls the handler associated with the route. By default, this is MvcHandler , which creates and uses the controller factory.

    To obtain the controller factory class, MvcHandler uses the ControllerBuilder class (implemented as a singleton ), which always contains a field with an instance of the controller factory. By default, ControllerBuilder contains and returns an instance of the DefaultControllerFactory class. However, a developer can define his controller factory with simple code in global.asax :

    protected void Application_Start()
    {
      RegisterRoutes(RouteTable.Routes);
      ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
    }

    * This source code was highlighted with Source Code Highlighter.

    where, ControllerFactory is the custom class of the controller factory.

    So, the controller factory, standard or user-defined, is created. After that, the CreateController method is called on it , which is passed the name of the controller class and the request context formed by the routing mechanism. Based on the database of these parameters, the factory must return an instance of the controller class or raise an exception.

    When using the standard controller factory, in the context of the request, among other things, a set of RequestContext.RouteData.DataTokens route parameters can be transferred, which can contain the namespace names (through the value of the Namespaces parameter) in which to search for the controller class. This can be useful and can speed up the application if your project has a lot of namespaces and the controllers are limited to only one. See the description of creating routes for details.

    Why and how to define your controller factory


    In fact, overriding the controller factory is a completely optional step for creating MVC Framework projects. However, a tool controlling the creation of controller classes may be useful to the developer.

    The most common use case for your controller factory is to implement an IoC / DI container, such as Unity , to instantiate controller classes through the container. The need and need for an IoC / DI container is the topic of other articles, but if you use such containers in a project, then redefining the controller factory can be a good way for you to create controllers through the container. A description of this implementation can be found in this article., here I will give only the class of the custom controller factory created using Unity:
    public class UnityControllerFactory : DefaultControllerFactory
    {
      IUnityContainer _container;

      public UnityControllerFactory(IUnityContainer container)
      {
        _container = container;
      }

      protected override IController GetControllerInstance(Type controllerType)
      {
        if (controllerType == null)
          throw new ArgumentNullException("controllerType");

        if (!typeof(IController).IsAssignableFrom(controllerType))
          throw new ArgumentException(string.Format(
            "Type requested is not a controller: {0}", controllerType.Name),
            "controllerType");

        return _container.Resolve(controllerType) as IController;
      }
    }

    * This source code was highlighted with Source Code Highlighter.

    As you can see, the new controller factory inherits from DefaultControllerFactory and overloads the GetControllerInstance method , which is used by DefaultControllerFactory to instantiate the controller class by its type.

    Another option for using a controller factory may be the introduction of black lists and white lists for controllers, which can or cannot be called through client requests. This may make sense when creating a large project with a mass of controllers that can be decommissioned for a while. If you implement a controller factory that will check against blacklists and whitelists, then you can easily solve the problem of removing a controller from use even at the stage of its creation. Moreover, for this you will neither need to edit the code, nor create new routes, nor recompile assemblies or restart the application. It will be enough to edit the “black” or “white” list, which can be represented even by an xml-file.

    Point


    We examined how the controller factory works. It is important to learn the following:
    • controller factory is called from the routing mechanism;
    • The controller factory instantiates controller classes
    • The factory of controllers can be redefined, but it is absolutely not necessary;
    • it is better to inherit your controller factory instance from the base class DefaultControllerFactory in order not to disrupt the operation of the MVC Framework mechanism;
    • if you use IoC / DI containers, then the controller factory will help you a lot.
    In the next article, we will begin to examine the operation of the ActionInvoker mechanism and associated attributes.

    Progg it

    Also popular now: