DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

How does AI transform chaos engineering from an experiment into a critical capability? Learn how to effectively operationalize the chaos.

Data quality isn't just a technical issue: It impacts an organization's compliance, operational efficiency, and customer satisfaction.

Are you a front-end or full-stack developer frustrated by front-end distractions? Learn to move forward with tooling and clear boundaries.

Developer Experience: Demand to support engineering teams has risen, and there is a shift from traditional DevOps to workflow improvements.

Related

  • Architecting Scalable ASP.NET Core Web APIs With Abstract Factory Method and Onion Architecture
  • GDPR Compliance With .NET: Securing Data the Right Way
  • Enabling Behavior-Driven Service Discovery: A Lightweight Approach to Augment Java Factory Design Pattern
  • How to Enhance the Performance of .NET Core Applications for Large Responses

Trending

  • Turbocharge Load Testing: Yandex.Tank + ghz Combo for Lightning-Fast Code Checks
  • Domain-Centric Agile Modeling for Legacy Insurance Systems
  • Understanding the Mandelbrot Set: A Beautiful Benchmark for Computing Power
  • How You Clear Your HTML5 Canvas Matters
  1. DZone
  2. Coding
  3. Frameworks
  4. Custom Controller Factory in ASP.NET MVC

Custom Controller Factory in ASP.NET MVC

By 
Keyvan Nayyeri user avatar
Keyvan Nayyeri
·
May. 12, 09 · News
Likes (1)
Comment
Save
Tweet
Share
27.7K Views

Join the DZone community and get the full member experience.

Join For Free

After discussing custom route handler and IRouteHandler as two extensibility points in ASP.NET MVC to customize the behavior of routing system, now I want to continue discussing thirteen major extensibility points in ASP.NET MVC by focusing on custom controller factories and building such controller factories.

When ASP.NET MVC receives a request, it needs to manage how to handle it with a specific controller and the action methods in it. The component that is responsible to map an incoming request to a specific controller and decide which controller to use is controller factory. There is a default controller factory in ASP.NET MVC that maps incoming requests to a controller with a Controller postfix.

The built-in controller factory is the registered controller factory by default and is implemented in DefaultControllerFactory class. Also it’s possible to extend its behavior with minor changes by deriving from this base class.

But in some circumstances you may need to have a fully customized behavior for your controller factories. One common example is when you use Dependency Injection frameworks where you need to use a customized factory. Fortunately, most of the DI frameworks provide such a customized controller factory out of the box, but if you were faced with a case to implement such a factory, you can implement the IControllerFactory interface and register your own custom controller factory.

IControllerFactory is an interface with two methods:

  • CreateController: Getting the RequestContext instance and the string value of controller name, returns the controller to be used.
  • ReleaseController: Gets a controller instance and releases this controller.

Implementation of a controller factory is comparatively easy, and can be done with less amount of work to be done.

In this post I implement a basic controller factory that loads controllers based on the user’s language, so a specific controller can be loaded for a specific language. In this sample application, I define the type name of controllers in web configuration file based on a pattern that corresponds to a specific culture, and implement a controller factory that loads the appropriate controllers group based on the client’s preferences.

First I define my type patterns in my configuration file as application settings. Here I have two cultures: if the user uses Farsi, then the Farsi controllers will be loaded, otherwise the default English language will be used.

<appSettings>
<add key="EnglishControllerTypePattern" value="IControllerFactorySample.Controllers.En.{0}"/>
<add key="FarsiControllerTypePattern" value="IControllerFactorySample.Controllers.Fa.{0}"/>
</appSettings>

Now I write my controller factory by implementing the IControllerFactory interface and its two methods.

using System;
using System.Configuration;
using System.Web.Mvc;
using System.Web.Routing;

namespace IControllerFactorySample.ControllerFactories
{
public class CustomControllerFactory : IControllerFactory
{
#region IControllerFactory Members

public IController CreateController(RequestContext requestContext, string controllerName)
{
if (string.IsNullOrEmpty(controllerName))
throw new ArgumentNullException("controllerName");

string language = requestContext.HttpContext.Request.Headers["Accept-Language"];

string controllerType = string.Empty;

if (language == "fa-IR")
controllerType = string.Format
(ConfigurationManager.AppSettings["FarsiControllerTypePattern"], controllerName);
else
controllerType = string.Format
(ConfigurationManager.AppSettings["EnglishControllerTypePattern"], controllerName);

IController controller = Activator.CreateInstance(Type.GetType(controllerType)) as IController;

return controller;
}

public void ReleaseController(IController controller)
{
if (controller is IDisposable)
(controller as IDisposable).Dispose();
else
controller = null;
}

#endregion
}
}

In the CreateController function, I detect the client’s language using the HTTP headers of the request, and load the appropriate type name based on the user’s culture. Then I use reflection APIs to load the type and create an instance of the controller to be returned. Note that this implementation doesn’t mandate the Controller postfix for controller names, so rather than defining my Home controller as HomeController class, I just can use Home name. I have defined my controllers in Fa and En sub-folders inside Controllers folder, so my controller factory can load them based on the type name patterns. Besides, in the ReleaseController method, I dispose the controller as expected.

The third and last step is to add this controller factory as the default factory to ASP.NET MVC. This can be done in Global.asax and its Application_Start method where I use ControllerBuilder.SetControllerFactory to add my factory type as the default controller factory to ASP.NET MVC.

using System.Web.Mvc;
using System.Web.Routing;
using IControllerFactorySample.ControllerFactories;

namespace IControllerFactorySample
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

}

protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);

ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
}
}
}

As you see, building a controller factory is very straightforward and you can get it done in a few simple steps. If I run the application and set my preferred language to Farsi, then Farsi controllers will be used to serve the requests, otherwise English controllers will be loaded.

As always, the sample application for this post is available for download.

 

ASP.NET MVC ASP.NET Factory (object-oriented programming)

Published at DZone with permission of Keyvan Nayyeri. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Architecting Scalable ASP.NET Core Web APIs With Abstract Factory Method and Onion Architecture
  • GDPR Compliance With .NET: Securing Data the Right Way
  • Enabling Behavior-Driven Service Discovery: A Lightweight Approach to Augment Java Factory Design Pattern
  • How to Enhance the Performance of .NET Core Applications for Large Responses

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: