Implementation of Separating Controller from Class Library in ASP.NET MVC

  • 2021-06-29 10:48:17
  • OfStack

Preface

In the development of, ASP.NET MVC, after we created the project, ASP.NET MVC exists as Model-Controller-View. Model is easy to separate into class libraries on the content that is automatically generated by the project, so don't tell us here, can we also separate like Controller at that time?The answer is yes, so let's explore how Controller can be separated.

Here I provide two separate methods, one is that the override method inherits from the IControllerFactory interface and implements the method inside, the other is that MVC provides direct control of the controller's writing within the routing registration. Here's a simple code for these two types.

Method 1

The code is as follows: Register in the route after writing the code.Tip: After the implementation is completed, it must be registered in the Routing Rules Method (RegisterRoutes), with the following registration code:

ControllerBuilder.Current.SetControllerFactory (new ControllersFactory ("BookSystem_Controllers ");//BookSystem_Controllers is a class library for controllers


//  Source file header information: 
// <copyright file="ControllersFactory.cs">
// Copyright(c)2014-2034 Kencery.All rights reserved.
//  Creator: Han Yinglong (kencery)
//  Creation time: 2015-6-18
// </copyright>

using System;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;

namespace BookSystem_Controllers
{
  /// <summary>
  ///  Rewrite the method of registering the controller so that it can be separated from other class libraries 
  /// <auther>
  ///   <name>kencery</name>
  ///   <date>2015-6-18</date>
  /// </auther>
  /// </summary>
  ///  Explain: IControllerFactory Interface contains 3 Methods to be implemented: CreateController , GetControllerSessionBehavior , ReleaseController
  ///  Use: In MVC App_Start In folder RouteConfig Method in RegisterRoutes In 1 Write the following registration statement on the line ,Global.asax Medium can also be registered, just before registering a route 
  /// ControllerBuilder.Current.SetControllerFactory(new ControllersFactory("BookSystem_Controllers")); //BookSystem_Controllers Class Library for Controller 
  public class ControllersFactory : IControllerFactory
  {
    private readonly string _assemblyName;
    private readonly string _controlerDefaultNameSpage;
    private Assembly _controllerAssembly;

    /// <summary>
    ///  Gets the assembly name where the controller is located 
    /// </summary>
    public string AssemblyName
    {
      get { return _assemblyName; }
    }

    /// <summary>
    ///  Get the default namespace for the controller 
    /// </summary>
    public string ControlerDefaultNameSpage
    {
      get { return _controlerDefaultNameSpage; }
    }

    /// <summary>
    ///  Gets the assembly in which the controller resides Assembly Example 
    /// </summary>
    public Assembly ControllerAssembly
    {
      get
      {
        return _controllerAssembly ?? (_controllerAssembly = Assembly.Load(AssemblyName)); // Load Controller Information 
      }
    }

    /// <summary>
    ///  Constructor instantiation 
    /// </summary>
    /// <param name="assemblyName"></param>
    public ControllersFactory(string assemblyName)
    {
      _assemblyName = assemblyName;
    }

    /// <summary>
    ///  Constructor instantiation 
    /// </summary>
    /// <param name="assemblyName"></param>
    /// <param name="controlerDefaultNameSpage"></param>
    public ControllersFactory(string assemblyName, string controlerDefaultNameSpage)
    {
      _assemblyName = assemblyName;
      _controlerDefaultNameSpage = controlerDefaultNameSpage;
    }

    /// <summary>
    ///  Gets the full name of the controller class 
    /// </summary>
    /// <param name="controllerName"> Controller name </param>
    public string GetControllerFullName(string controllerName)
    {
      return string.Format("{0}.{1}Controller",
        string.IsNullOrEmpty(ControlerDefaultNameSpage) ? AssemblyName : ControlerDefaultNameSpage,
        controllerName);
    }

    /// <summary>
    ///  Gets the controller instance object, based on controllerName generate 1 An empty controller for which there is no request context object ControllerContext Object, and then returns the controller instance 
    /// </summary>
    /// <param name="requestContext"></param>
    /// <param name="controllerName"></param>
    public IController CreateController(RequestContext requestContext, string controllerName)
    {
      var controller = ControllerAssembly.CreateInstance(GetControllerFullName(controllerName)) as Controller;
      if (controller == null)
        return null;
      if (controller.ControllerContext == null)
      {
        controller.ControllerContext = new ControllerContext(requestContext, controller);
      }
      else
      {
        controller.ControllerContext.RequestContext = requestContext;
      }
      return controller;
    }

    /// <summary>
    ///  Support type for returning the requested session state 
    /// </summary>
    /// <param name="requestContext"></param>
    /// <param name="controllerName"></param>
    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
    {
      var controllerType = ControllerAssembly.GetType(GetControllerFullName(controllerName), true, true);
      var sessionStateAttr =
        Attribute.GetCustomAttribute(controllerType, typeof (SessionStateAttribute), false) as
          SessionStateAttribute;
      return sessionStateAttr == null ? SessionStateBehavior.Default : sessionStateAttr.Behavior;
    }

    /// <summary>
    ///  Release Resources 
    /// </summary>
    /// <param name="controller"></param>
    public void ReleaseController(IController controller)
    {
      var idDisposable = controller as IDisposable;
      if (idDisposable != null)
      {
        idDisposable.Dispose();
      }
    }
  }
}

Method 2

The routing registration method code is as follows: The disadvantage is that if you have more than one routing registration rule, you must remember to add the namespaces attribute or an error will occur


// System Default Route 
    routes.MapRoute(
      name: "Default",
      url: "{controller}/{action}/{id}",
      defaults: new {controller = "Login", action = "Index", id = UrlParameter.Optional},
      namespaces: new string[] {"BookSystem_Controllers"}
);


Related articles: