Spring.NET 1.3.1 新特性探索系列1——ASP.NET MVC的依赖注入
Spring.NET 1.3.1的程序集Spring.Web.Mvc提供对ASP.NET MVC程序的整合。其中SpringControllerFactory类继承自DefaultControllerFactory,以便于实现Spring.NET对Controller的管理
SpringControllerFactory
public class SpringControllerFactory : DefaultControllerFactory
{
private static IApplicationContext _context;
/// <summary>
/// Gets the application context.
/// </summary>
/// <value>The application context.</value>
public static IApplicationContext ApplicationContext
{
get
{
if (_context == null || _context.Name != ApplicationContextName)
{
if (string.IsNullOrEmpty(ApplicationContextName))
{
_context = ContextRegistry.GetContext();
}
else
{
_context = ContextRegistry.GetContext(ApplicationContextName);
}
}
return _context;
}
}
/// <summary>
/// Gets or sets the name of the application context.
/// </summary>
/// <remarks>
/// Defaults to using the root (default) Application Context.
/// </remarks>
/// <value>The name of the application context.</value>
public static string ApplicationContextName { get; set; }
/// <summary>
/// Creates the specified controller by using the specified request context.
/// </summary>
/// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
/// <param name="controllerName">The name of the controller.</param>
/// <returns>A reference to the controller.</returns>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext"/> parameter is null.</exception>
/// <exception cref="T:System.ArgumentException">The <paramref name="controllerName"/> parameter is null or empty.</exception>
public override IController CreateController(RequestContext requestContext, string controllerName)
{
IController controller;
if (ApplicationContext.ContainsObjectDefinition(controllerName))
{
controller = ApplicationContext.GetObject(controllerName) as IController;
}
else
{
controller = base.CreateController(requestContext, controllerName);
}
AddActionInvokerTo(controller);
return controller;
}
/// <summary>
/// Retrieves the controller instance for the specified request context and controller type.
/// </summary>
/// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
/// <param name="controllerType">The type of the controller.</param>
/// <returns>The controller instance.</returns>
/// <exception cref="T:System.Web.HttpException">
/// <paramref name="controllerType"/> is null.</exception>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="controllerType"/> cannot be assigned.</exception>
/// <exception cref="T:System.InvalidOperationException">An instance of <paramref name="controllerType"/> cannot be created.</exception>
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
IController controller = null;
if (controllerType != null)
{
var controllers = ApplicationContext.GetObjectsOfType(controllerType);
if (controllers.Count > 0)
{
controller = (IController)controllers.Cast<DictionaryEntry>().First<DictionaryEntry>().Value;
}
}
else
{
//pass to base class for remainder of handling if can't find it in the context
controller = base.GetControllerInstance(requestContext, controllerType);
}
AddActionInvokerTo(controller);
return controller;
}
/// <summary>
/// Adds the action invoker to the controller instance.
/// </summary>
/// <param name="controller">The controller.</param>
protected virtual void AddActionInvokerTo(IController controller)
{
if (controller == null)
return;
if (typeof(Controller).IsAssignableFrom(controller.GetType()))
{
((Controller)controller).ActionInvoker = new SpringActionInvoker(ApplicationContext);
}
}
}
{
private static IApplicationContext _context;
/// <summary>
/// Gets the application context.
/// </summary>
/// <value>The application context.</value>
public static IApplicationContext ApplicationContext
{
get
{
if (_context == null || _context.Name != ApplicationContextName)
{
if (string.IsNullOrEmpty(ApplicationContextName))
{
_context = ContextRegistry.GetContext();
}
else
{
_context = ContextRegistry.GetContext(ApplicationContextName);
}
}
return _context;
}
}
/// <summary>
/// Gets or sets the name of the application context.
/// </summary>
/// <remarks>
/// Defaults to using the root (default) Application Context.
/// </remarks>
/// <value>The name of the application context.</value>
public static string ApplicationContextName { get; set; }
/// <summary>
/// Creates the specified controller by using the specified request context.
/// </summary>
/// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
/// <param name="controllerName">The name of the controller.</param>
/// <returns>A reference to the controller.</returns>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext"/> parameter is null.</exception>
/// <exception cref="T:System.ArgumentException">The <paramref name="controllerName"/> parameter is null or empty.</exception>
public override IController CreateController(RequestContext requestContext, string controllerName)
{
IController controller;
if (ApplicationContext.ContainsObjectDefinition(controllerName))
{
controller = ApplicationContext.GetObject(controllerName) as IController;
}
else
{
controller = base.CreateController(requestContext, controllerName);
}
AddActionInvokerTo(controller);
return controller;
}
/// <summary>
/// Retrieves the controller instance for the specified request context and controller type.
/// </summary>
/// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
/// <param name="controllerType">The type of the controller.</param>
/// <returns>The controller instance.</returns>
/// <exception cref="T:System.Web.HttpException">
/// <paramref name="controllerType"/> is null.</exception>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="controllerType"/> cannot be assigned.</exception>
/// <exception cref="T:System.InvalidOperationException">An instance of <paramref name="controllerType"/> cannot be created.</exception>
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
IController controller = null;
if (controllerType != null)
{
var controllers = ApplicationContext.GetObjectsOfType(controllerType);
if (controllers.Count > 0)
{
controller = (IController)controllers.Cast<DictionaryEntry>().First<DictionaryEntry>().Value;
}
}
else
{
//pass to base class for remainder of handling if can't find it in the context
controller = base.GetControllerInstance(requestContext, controllerType);
}
AddActionInvokerTo(controller);
return controller;
}
/// <summary>
/// Adds the action invoker to the controller instance.
/// </summary>
/// <param name="controller">The controller.</param>
protected virtual void AddActionInvokerTo(IController controller)
{
if (controller == null)
return;
if (typeof(Controller).IsAssignableFrom(controller.GetType()))
{
((Controller)controller).ActionInvoker = new SpringActionInvoker(ApplicationContext);
}
}
}
让我们开始实现对ASP.NET依赖注入的实现。
一、首先引用程序集Spring.Web.Mvc.dll,此程序可以脱离Spring.NET独立使用。
二、修改MvcApplication类,继承SpringMvcApplication。
让我们看下SpringMvcApplication类的代码
SpringMvcApplication
public abstract class SpringMvcApplication : HttpApplication
{
/// <summary>
/// Handles the Start event of the Application control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected virtual void Application_Start(object sender, EventArgs e)
{
RegisterAreas();
RegisterRoutes(RouteTable.Routes);
}
/// <summary>
/// Configures the <see cref="Spring.Context.IApplicationContext"/> instance.
/// </summary>
/// <remarks>
/// You must override this method in a derived class to control the manner in which the
/// <see cref="Spring.Context.IApplicationContext"/> is configured.
/// </remarks>
protected virtual void ConfigureApplicationContext()
{
}
/// <summary>
/// Executes custom initialization code after all event handler modules have been added.
/// </summary>
public override void Init()
{
base.Init();
//the Spring HTTP Module won't have built the context for us until now so we have to delay until the init
ConfigureApplicationContext();
RegisterSpringControllerFactory();
}
/// <summary>
/// Registers the areas.
/// </summary>
/// <remarks>
/// Override this method in a derived class to modify the registered areas as neeeded.
/// </remarks>
protected virtual void RegisterAreas()
{
AreaRegistration.RegisterAllAreas();
}
/// <summary>
/// Registers the routes.
/// </summary>
/// <remarks>
/// Override this method in a derived class to modify the registered routes as neeeded.
/// </remarks>
protected virtual void RegisterRoutes(RouteCollection routes)
{
// This IgnoreRoute call is provided to avoid the trouble of CASSINI passing all req's thru
// ASP.NET (and thus the controller pipeline) during debugging
// see http://stackoverflow.com/questions/487230/serving-favicon-ico-in-asp-net-mvc and elsewhere for more info
routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
/// <summary>
/// Registers the controller factory with the Mvc Framework.
/// </summary>
protected virtual void RegisterSpringControllerFactory()
{
ControllerBuilder.Current.SetControllerFactory(typeof(SpringControllerFactory));
}
}
{
/// <summary>
/// Handles the Start event of the Application control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected virtual void Application_Start(object sender, EventArgs e)
{
RegisterAreas();
RegisterRoutes(RouteTable.Routes);
}
/// <summary>
/// Configures the <see cref="Spring.Context.IApplicationContext"/> instance.
/// </summary>
/// <remarks>
/// You must override this method in a derived class to control the manner in which the
/// <see cref="Spring.Context.IApplicationContext"/> is configured.
/// </remarks>
protected virtual void ConfigureApplicationContext()
{
}
/// <summary>
/// Executes custom initialization code after all event handler modules have been added.
/// </summary>
public override void Init()
{
base.Init();
//the Spring HTTP Module won't have built the context for us until now so we have to delay until the init
ConfigureApplicationContext();
RegisterSpringControllerFactory();
}
/// <summary>
/// Registers the areas.
/// </summary>
/// <remarks>
/// Override this method in a derived class to modify the registered areas as neeeded.
/// </remarks>
protected virtual void RegisterAreas()
{
AreaRegistration.RegisterAllAreas();
}
/// <summary>
/// Registers the routes.
/// </summary>
/// <remarks>
/// Override this method in a derived class to modify the registered routes as neeeded.
/// </remarks>
protected virtual void RegisterRoutes(RouteCollection routes)
{
// This IgnoreRoute call is provided to avoid the trouble of CASSINI passing all req's thru
// ASP.NET (and thus the controller pipeline) during debugging
// see http://stackoverflow.com/questions/487230/serving-favicon-ico-in-asp-net-mvc and elsewhere for more info
routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
/// <summary>
/// Registers the controller factory with the Mvc Framework.
/// </summary>
protected virtual void RegisterSpringControllerFactory()
{
ControllerBuilder.Current.SetControllerFactory(typeof(SpringControllerFactory));
}
}
这样,我们在增加Route规则的时候,可以重写RegisterRoutes方法。
MvcApplication
public class MvcApplication : SpringMvcApplication
{
protected override void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
);
}
}
{
protected override void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
);
}
}
三、给HomeController增加一个属性。
HomeController
public class HomeController : Controller
{
public string Message { get; set; }
public ActionResult Index()
{
ViewData["Message"] = this.Message;
return View();
}
public ActionResult About()
{
return View();
}
}
{
public string Message { get; set; }
public ActionResult Index()
{
ViewData["Message"] = this.Message;
return View();
}
public ActionResult About()
{
return View();
}
}
四、增加Controller配置Controllers.xml。
Controllers.xml
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
<object type="SpringMvcApp.Controllers.HomeController, SpringMvcApp" singleton="false" >
<property name="Message" value="Spring.NET 1.3.1 的 ASP.NET MVC 依赖注入" />
</object>
</objects>
<objects xmlns="http://www.springframework.net">
<object type="SpringMvcApp.Controllers.HomeController, SpringMvcApp" singleton="false" >
<property name="Message" value="Spring.NET 1.3.1 的 ASP.NET MVC 依赖注入" />
</object>
</objects>
五、配置Web.config
Web.config
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="~/Config/Controllers.xml"/>
</context>
</spring>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="~/Config/Controllers.xml"/>
</context>
</spring>
运行效果
博库出处:http://www.cnblogs.com/GoodHelper/archive/2010/12/22/SpringNet131Mcv.html
欢迎转载,但需保留版权。
作者:刘冬.NET
博客地址:http://www.cnblogs.com/GoodHelper/
欢迎转载,但须保留版权