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

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

2016-04-26 08:59 645 查看
http://blog.csdn.net/educast/article/details/7691925

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