看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