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 { getset; }

        
/// <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));
        }

    }

 

 

 

  这样,我们在增加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 } // 参数默认值
            );

        }
    }

 

 

  三、给HomeController增加一个属性。

 

HomeController
public class HomeController : Controller
    {
        
public string Message { getset; }

        
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>

 

 

  五、配置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>

 

        

  运行效果

 

 

 

  博库出处:http://www.cnblogs.com/GoodHelper/archive/2010/12/22/SpringNet131Mcv.html

  欢迎转载,但需保留版权。

  代码下载

posted @ 2010-12-22 12:14  冬子哥  阅读(11818)  评论(21编辑  收藏  举报