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的容器中。
  • 相关阅读:
    mongoDB在windows下安装和配置.
    node 中的定时器, nextTick()和setImmediate()的使用
    node 通过指令创建一个package.json文件
    node 中 npm报错 Error: ENOENT, stat 'C:UsersAdministratorAppDataRoaming pm'
    canvas之太阳系效果
    canvas之抒写文字
    canvas之绘制一张图片
    canvas之画一个三角形
    canvas之旋转一条线段
    unity3d 2d游戏制作的模式
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2363483.html
Copyright © 2011-2022 走看看