ASP.NET MVC 整合 Spring.net(1)- Controller进容器

我们都知道Asp.net MVC自有一套执行机制。
通过分析MVC的MvcHandler关键代码

 

ExpandedBlockStart.gif ProcessRequest
         protected   internal   virtual   void  ProcessRequest(HttpContextBase httpContext) {
            AddVersionHeader(httpContext);

            
//  Get the controller type
             string  controllerName  =  RequestContext.RouteData.GetRequiredString( " controller " );

            
//  Instantiate the controller and call Execute
            IControllerFactory factory  =  ControllerBuilder.GetControllerFactory();
            IController controller 
=  factory.CreateController(RequestContext, controllerName);
            
if  (controller  ==   null ) {
                
throw   new  InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentUICulture,
                        MvcResources.ControllerBuilder_FactoryReturnedNull,
                        factory.GetType(),
                        controllerName));
            }
            
try  {
                controller.Execute(RequestContext);
            }
            
finally  {
                factory.ReleaseController(controller);
            }
        }

 

 

我们可以认为MVC中Controller都是基于工厂模式来创建对象的。
 
但是要利用Spring.net实现IOC和AOP,就必须管理这个框架中具体对象的创建工作。
即通过配置文件的方式决定一个具体对象的生或死!
ExpandedBlockStart.gif Objects
< objects  xmlns ="http://www.springframework.net/" >
  
  
< object  id ="Demos.Domain.Object" >
    
< property  name ="Target" >
      
< object  type ="Demos.Domain.Object,Demos.Domain" >
        
< property  name ="Manager"  ref ="Demos.Domain.Manager" />
      
</ object >
    
</ property >
  
</ object >
</ objects >

 

 
但是MVC框架自己的运行机制决定了Controller的创建不会经过Spring。
 
幸好,MVC留下了一个叫做SetControllerFactory的扩展。
即,程序运行之初我们就可以用自己的ControllerFactory替换默认的ControllerFactory.

        protected void Application_Start()
        {
            //用自定义的构造工厂替换默认的
            ControllerBuilder.Current.SetControllerFactory(typeof(Demo.Core.ControllerFactory));

            RegisterRoutes(RouteTable.Routes);
        }

 

 
这样我们自己的工厂进行替换默认的Controller工厂后,就可以控制Controller的创建了。
 

我们自己的Controller工厂的代码

ExpandedBlockStart.gif ControllerFactory
using  System.Web.Mvc;
using  System.Web.Routing;
using  Spring.Context;

namespace  Demo.Core
{
    
public   class  ControllerFactory : IControllerFactory
    {
        
///   <summary>
        
///  Default ControllerFactory
        
///   </summary>
         private   static  DefaultControllerFactory defalutf  =   null ;

        
public  IController CreateController(RequestContext requestContext,  string  controllerName)
        {
            
string  controller  =  controllerName  +   " Controller " ;
            IApplicationContext ctx 
=  Container.GetContext();

            
if  (ctx.ContainsObject(controller))
            {
                
object  controllerf  =  ctx.GetObject(controller);
                
return  (IController)controllerf;
            }
            
else
            {
                
if  (defalutf  ==   null )
                {
                    defalutf 
=   new  DefaultControllerFactory();
                }
                    
                
return  defalutf.CreateController(requestContext, controllerName);
            }
        }

        
public   void  ReleaseController(IController controller)
        {
            IApplicationContext ctx 
=  Container.GetContext();

            
if  ( ! ctx.ContainsObject(controller.GetType().Name))
            {
                
if  (defalutf  ==   null )
                {
                    defalutf 
=   new  DefaultControllerFactory();
                }

                defalutf.ReleaseController(controller);
            }
        }
    }
}

 

 

 Spring.net 容器包装的代码

 

ExpandedBlockStart.gif Container
using  System;
using  System.Collections;
using  System.Collections.Generic;
using  Spring.Context;
using  Spring.Context.Support;

namespace  Demo.Core
{
    
public   class  Container
    {
        
///   <summary>
        
///  获取应用程序上下文.
        
///   </summary>
        
///   <returns><see cref="IApplicationContext"/> 应用程序上下文. </returns>
         public   static  IApplicationContext GetContext()
        {
            
if  (FApplicationContext  ==   null )
            {
                FApplicationContext 
=  ContextRegistry.GetContext();
            }
            
return  FApplicationContext;
        }

        
///   <summary>
        
///  获取应用程序上下文.
        
///   </summary>
        
///   <param name="name"><see cref="IApplicationContext"/> 应用程序上下文名称. </param>
        
///   <returns><see cref="IApplicationContext"/> 应用程序上下文. </returns>
         public   static  IApplicationContext GetContext( string  name)
        {
            
return  ContextRegistry.GetContext(name);
        }

        
///   <summary>
        
///  获取对象.
        
///   </summary>
        
///   <typeparam name="T"> 对象的类型. </typeparam>
        
///   <param name="id"> 标识. </param>
        
///   <returns></returns>
         public   static  T GetObject < T > ( string  id)
        {
            
return  (T)GetContext().GetObject(id);
        }

        
///   <summary>
        
///  获取对象类表.
        
///   </summary>
        
///   <typeparam name="T"> 对象的类型. </typeparam>
        
///   <returns></returns>
         public   static  IList < T >  GetObjects < T > ()
        {
            IEnumerable items 
=  GetContext().GetObjectsOfType( typeof (T));
            IList
< T >  objects  =   new  List < T > ();
            
foreach  (DictionaryEntry item  in  items)
            {
                objects.Add((T)item.Value);
            }
            
return  objects;
        }

        [ThreadStatic]
        
private   static  IApplicationContext FApplicationContext;
    }
}

 

 

然后我们再新建个Demos.Controllers的项目。

using System.Web.Mvc;

namespace Demo.Controllers
{
    public class DemoController : Controller
    {
        public ViewResult Index()
        {
            ViewData["Message"] = "Welcome to IOC MVC";
            return View();
        }
    }
}

 

 
相应Dll的配置文件
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns=" http://www.springframework.net/">
  <object id="DemoController" type="Demo.Controllers.DemoController, Demo.Controllers" singleton="false" >
  </object>
</objects>

 

并把配置文件设置为嵌入资源

然后再在Web.config中添加相应配置

 

ExpandedBlockStart.gif Web.config
   < sectionGroup name = " spring " >
      
< section name = " context "  type = " Spring.Context.Support.WebContextHandler, Spring.Web "   />
      
< section name = " objects "  type = " Spring.Context.Support.DefaultSectionHandler, Spring.Core "   />
  
</ sectionGroup >

  
< spring >
    
< context >
      
< resource uri = " config://spring/objects "   />
      
< resource uri = " assembly://Demo.Controllers/Demo.Controllers/Controllers.xml "   />
    
</ context >
    
< objects xmlns = " http://www.springframework.net "   />
  
</ spring >

 

 

 
测试运行,我们可以发现这个DemoController已在Spring的容器中。

转载于:https://www.cnblogs.com/moshe/archive/2010/02/07/1665344.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值