日期:2014-05-16 浏览次数:20982 次
IIS 接收到一个http请求,进入w3wp进程(如果是webgarden,先找到一个压力小的的w3wp),找到applicationpool,进入global.asax,进入路由,从controllerfactory找到一个controller,如果我们用了默认的controller,会解析出action名称和参数调用action(也可以手动直接在controller处理掉请求),返回并执行result,如图:

在上一章节,介绍了如果customize 一个controller(实现IController接口),现在介绍一个如何customizecontroller factory。
接口:
public interface IControllerFactory {
IController CreateController(RequestContextrequestContext,
string controllerName);
SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext,
string controllerName);
void ReleaseController(IControllercontroller);
}
说明:
CreateController : 接收request context和controller name(不包含”Controller”后缀),返回一个IController对象,用于创建Controller对象
GetControllerSessionBehavior:参数同上,返回一个SessionStateBehavior,控制创建出的controller的sessionstate对象
ReleaseController:
如果controller包含了一些需要手动释放的资源,可以在这个函数里统一释放
代码示例:
public class CustControllerFactory : IControllerFactory
{
private string_nsFind;
private string_assembly;
public CustControllerFactory(string namespaceFind, string assemblyName)
{
if(namespaceFind.Last() == '.') namespaceFind =namespaceFind.Remove(namespaceFind.Length - 1);
_nsFind =namespaceFind;
_assembly= assemblyName;
}
public IController CreateController(RequestContext requestContext, string controllerName)
{
var fullName = _nsFind + "." + controllerName + "Controller";
var type =GetType().Assembly.GetTypes().FirstOrDefault(t => t.FullName == fullName);
if (type== null)
{
return new TestController();
}
return (IController)Activator.CreateInstance(_assembly, fullName).Unwrap();
}
public SessionStateBehavior GetControllerSessionBehavior(RequestContextrequestContext, string controllerName)
{
return SessionStateBehavior.Default;
}
public void ReleaseController(IController controller)
{
var disposable = controller as IDisposable;
if(disposable != null)
{
disposable.Dispose();
}
}
}代码说明:factory接收一个命名空间名称和assembly名称,在指定的范围内检索controller对象通过反射动态创建对象,如果找不到,返回一个默认的controller。
下一步,在global文件中注册factory:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ControllerBuilder.Current.SetControllerFactory(new
CustControllerFactory("MVCRouteStudy.Controllers","MVCRouteStudy"));
}
可以看到,在最后一行,我注册了我手动创建的factory。
测试一下这个factory,先访问一个不存在controller:

访问一个存在的:

注意:此例只作为一个简单的实现,甚至没有捕捉异常。现实应用中,场景要复杂的多,自定义的controller工厂在创建controller对象时,一般不仅仅简单的创建一个实