您的位置:首页 > 编程语言 > ASP

ASP.NET MVC 整合 Spring.net- Controller注入

2012-06-26 10:15 459 查看
我们都知道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的容器中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: