Oxite 之 ControllerActionInvoker应用
2009-04-02 17:03 无常 阅读(748) 评论(0) 收藏 举报看Oxite的源码时遇到个很困惑的问题,在Oxite的Controller中,很多Action返回值不是我们常见的ActionResult类型,比如说这里:
| public class PageController : Controller |
| { |
| //.... |
| public virtual OxiteModelItem<Page> Item(string pagePath) |
| { |
| Page page = pageService.GetPage(pagePath); |
| if (page == null) return null; |
| return new OxiteModelItem<Page> |
| { |
| Item = page |
| }; |
| } |
| //..... |
| } |
OxiteModeItem是何许人也?起初以为是ActionResult的派生类,是这样吗?到Oxite.ViewModels中我们可以看个究竟,
| public class OxiteModel |
| { |
| public INamedEntity Container { get; set; } |
| public SiteViewModel Site { get; set; } |
| public UserViewModel User { get; set; } |
| private readonly Dictionary<Type, object> modelItems = new Dictionary<Type, object>(); |
| public void AddModelItem<T>(T modelItem) where T : class |
| { |
| modelItems[typeof(T)] = modelItem; |
| } |
| public T GetModelItem<T>() where T : class |
| { |
| if (modelItems.ContainsKey(typeof(T))) |
| return modelItems[typeof(T)] as T; |
| return null; |
| } |
| //.... |
| } |
并非如我所想,在这个目录中还有几个它儿子,继承层次如下

竟然不是派生于ActionResult,只是下原汁原味的Model,纳闷了,MVC中的V到哪里去了?
如果之前没接触过IOC,看Oxite的代码时确实是有点头晕,好不容易才把OxiteControllerActionInvoker翻出来了。先来看下它的代码
| namespace Oxite.Infrastructure |
| { |
| public class OxiteControllerActionInvoker : ControllerActionInvoker |
| { |
| private readonly IFilterRegistry filterRegistry; |
| public OxiteControllerActionInvoker(IFilterRegistry filterRegistry) |
| { |
| this.filterRegistry = filterRegistry; |
| } |
| protected override ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue) |
| { |
| if (actionReturnValue == null) |
| { |
| controllerContext.Controller.ViewData.Model = new OxiteModel { Container = new NotFoundPageContainer() }; |
| return new NotFoundResult(); |
| } |
| if (typeof(ActionResult).IsAssignableFrom(actionReturnValue.GetType())) |
| return actionReturnValue as ActionResult; |
| controllerContext.Controller.ViewData.Model = actionReturnValue; |
| return new ViewResult { ViewData = controllerContext.Controller.ViewData, TempData = controllerContext.Controller.TempData }; |
| } |
| //.... |
| } |
| } |
在这里可以看到个明白,actionReturnValue就是就是控制器中返回的结果,在这里首先判断是否为空,然后判断返回结果的类型是否从ActionResult派生出来的,如果是,说明是个View,直接交出去了,否则就是Model了。
当然这里还离不开另一个类OxiteControllerFactory:
| namespace Oxite.Infrastructure |
| { |
| public class OxiteControllerFactory : DefaultControllerFactory |
| { |
| private readonly IUnityContainer container; |
| public OxiteControllerFactory(IUnityContainer container) |
| { |
| this.container = container; |
| } |
| protected override IController GetControllerInstance(Type controllerType) |
| { |
| IController iController = container.Resolve(controllerType) as IController; |
| if (typeof(Controller).IsAssignableFrom(controllerType)) |
| { |
| Controller controller = iController as Controller; |
| if (controller != null) |
| controller.ActionInvoker = container.Resolve<IActionInvoker>(); |
| return iController; |
| } |
| return iController; |
| } |
| } |
| } |
ControllerFactory看名字就知道是做什么用的了,在控制器创建了之后,直接指定自己的ActionInvoker。
推荐二篇关于ActionInvoker的文章:
http://lostintangent.com/2008/07/03/aspnet-mvc-controlleractioninvoker-part-1/
http://lostintangent.com/2008/07/07/aspnet-mvc-controlleractioninvoker-part-2/
from : wuchang.cnblos.com
浙公网安备 33010602011771号