Use spring. Net 1.3.2 to implement container (IOC) (2) ASP. net mvc and controllerfactory

Source: Internet
Author: User
Controllerfactory

Controllerfactory is a routing-based component that selects the correct controller and instantiates it. The default factory searches for classes that implement the icontroller and end with the Controller, and then instantiates the class using a non-argument constructor through reflection.

However, if you want to use dependency injection, you cannot use the default factory. Instead, you must use the Controller factory that supports IOC.

The Controller factory that supports IOC (dependency injection) has the advantage of loose coupling and good testability. If you want to use some services in the controller, either new or Singleton, such as userservice. in this way, it is not easy to write unit tests to the Controller. It is too tightly coupled with these services and cannot replace these services with stub implementation. Therefore, loose coupling is required. To implement this function, you must allow the dependency injection framework to create a controller to inject dependencies and assemble objects. There is a controllerfactory in MVC that can be used for this purpose.

Method:

1. Write a class that inherits from defaultcontrollerfactory. For example, springcontrollerfactory: defaultcontrollerfactory
2. Override the getcontrollerinstance method and use the dependency injection framework to create a conroller.
3. modify global. asax. CS and register and use your own controllerfactory in application_start,

ControllerBuilder.Current.SetControllerFactory(new SpringControllerFactory())

4. Inject constructor into the controller, for example:

    public class AccountController : Controller
{
private IRepository repository;

public IRepository Repository
{
get
{
return repository;
}
set
{
repository = value;
}
}
}

From now on, all controllers are created through the dependency injection framework, and newly added services are registered in the dependency injection framework. The controller adds the services to the constructor, the framework is injected.

Controllerfactory of mvcquick

In "using spring. Net 1.3.2 to implement container (IOC) (1)", spring. net has been used to implement a simple IOC container classiccontainer. Therefore, controllerfactory that supports IOC is implemented.
Hand to hand.

Mvcquick's controllerfactory implementation code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Collections;
using MVCQuick.Framework.Container;

namespace MVCQuick.Framework.Mvc
{
public class ClassicControllerFactory : DefaultControllerFactory
{
public override IController CreateController(RequestContext requestContext, string controllerName)
{
IController controller = ClassicContainer.GetObject(controllerName) as IController;

if (controller == null)
{
controller = base.CreateController(requestContext, controllerName);
}

AddActionInvokerTo(controller);

return controller;
}

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
IController controller = null;

if (controllerType != null)
{
var controllers = ClassicContainer.GetObjects(controllerType);

if (controllers.Count > 0)
{
controller = (IController)controllers.Cast<DictionaryEntry>().First().Value;
}
}
else
{
controller = base.GetControllerInstance(requestContext, controllerType);
}

AddActionInvokerTo(controller);

return controller;
}

protected virtual void AddActionInvokerTo(IController controller)
{
if (controller == null)
return;

if (typeof(Controller).IsAssignableFrom(controller.GetType()))
{
((Controller)controller).ActionInvoker = new ClassicActionInvoker();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCQuick.Framework.Container;

namespace MVCQuick.Framework.Mvc
{
///<summary>
/// ActionInvoker implementation that enables the <see cref="IApplicationContext"/>to satisfy dependencies on ActionFilter attributes.
///</summary>
public class ClassicActionInvoker : ControllerActionInvoker
{

///<summary>
///
///</summary>
public ClassicActionInvoker()
{

}

///<summary>
/// Retrieves information about the action filters.
///</summary>
///<param name="controllerContext">The controller context.</param>
///<param name="actionDescriptor">The action descriptor.</param>
///<returns>Information about the action filters.</returns>
protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
//let the base class do the actual work as usual
var filterInfo = base.GetFilters(controllerContext, actionDescriptor);

//configure each collection of filters using the IApplicationContext
foreach (IActionFilter filter in filterInfo.ActionFilters.Where(f => f != null))
{
ClassicContainer.ConfigureObject(filter, filter.GetType().FullName);
}

foreach (IAuthorizationFilter filter in filterInfo.AuthorizationFilters.Where(f => f != null))
{
ClassicContainer.ConfigureObject(filter, filter.GetType().FullName);
}

foreach (IExceptionFilter filter in filterInfo.ExceptionFilters.Where(f => f != null))
{
ClassicContainer.ConfigureObject(filter, filter.GetType().FullName);
}

foreach (IResultFilter filter in filterInfo.ResultFilters.Where(f => f != null))
{
ClassicContainer.ConfigureObject(filter, filter.GetType().FullName);
}

return filterInfo;
}

}
}

 

Classiccontrollerfactory usage

Add code in the global. asax. CS class application_start ()

//Register Repository
ClassicContainer.Register<NHibernateRepository>("NHibernateRepository");
//Register  Controller
IDictionary properties = new Dictionary<String, Object>();
properties.Add("Repository", ClassicContainer.GetObject("NHibernateRepository"));
ClassicContainer.Register<AccountController>("Account", properties);
ClassicContainer.Register<CheckoutController>("Checkout", properties);
ClassicContainer.Register<HomeController>("Home", properties);
ClassicContainer.Register<ShoppingCartController>("ShoppingCart", properties);
ClassicContainer.Register<StoreController>("Store", properties);
ClassicContainer.Register<StoreManagerController>("StoreManager", properties);
ClassicContainer.Register<SampleDataController>("SampleData", properties);
       
//Set ControllerFactory
ControllerBuilder.Current.SetControllerFactory(typeof(ClassicControllerFactory));

 

Source code download: http://mvcquick.codeplex.com/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.