zoukankan      html  css  js  c++  java
  • Asp.net MVS 集成Spring.net机制原理及实现

    我们都知道Asp.net MVC自有一套执行机制。


    通过分析MVC的MvcHandler关键代码


     


    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,就必须管理这个框架中具体对象的创建工作。

    即通过配置文件的方式决定一个具体对象的生或死!


    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工厂的代码


    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 容器包装的代码


     


    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中添加相应配置


     


    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的容器中。
  • 相关阅读:
    UVA 10617 Again Palindrome
    UVA 10154 Weights and Measures
    UVA 10201 Adventures in Moving Part IV
    UVA 10313 Pay the Price
    UVA 10271 Chopsticks
    Restore DB後設置指引 for maximo
    每行SQL語句加go換行
    种服务器角色所拥有的权限
    Framework X support IPV6?
    模擬DeadLock
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2363483.html
Copyright © 2011-2022 走看看