Oxite 之 ControllerActionInvoker应用
2009-04-02 17:03 无常 阅读(740) 评论(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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架