原理不难理解,主要还是反射,因为我们当前请求的控制器类在测试项目里面,所以反射的时候需要指定当前测试项目的程序集,通过这里的代码可以看出,在UrlRoutingModule里面封装的RequestContext对象实在是太重要了,因为各个地方都需要用到它。博主觉得这里还有待优化,等想到更好的办法再来逐步优化。此步得到结果:
(9)得到控制器对象之后,就是执行Action方法了: controller.Execute(context.Request.RequestContext); 。这里博主按照源码里面的构造封装了IController、ControllerBase、Controller三个级别的接口以及父类。Execute方法的实现在Controller里面:
Controller:ControllerBase,IDisposable { Execute(System.Web.Routing.RequestContext requestContext) { //反射得到Action方法 Type type = this.GetType(); ); System.Reflection.MethodInfo mi = type.GetMethod(actionName); //执行该Action方法 mi.Invoke( }
这里再次用到了RequestContext对象,由此可以看出,RequestContext对象几乎贯穿整个MvcHandler,再次应征了上述注释(3)中说的它的重要性。
上述代码就是通过反射Action方法,然后执行该方法,之后请求就会尽到我们HomeController的Index()方法里面。
(10)执行Index()方法
请求进入到Index()方法之后,然后就是从Model里面获取数据,再然后就是返回View,整个MVC的原理就是如此。当然博主这里的Swift.MVC还只是将请求转到了Index里面,剩余的Model可以自己写,但是View的部分还完全没有,待有时间完善。
(11)执行完Action之后,最后就是释放当前的Controller对象了。在finally里面有这么一句: factory.ReleaseController(controller); 。还是来看看ReleaseController方法的定义:
ReleaseController(IController controller) { IDisposable disposable = controller as IDisposable; if (disposable != null) { disposable.Dispose(); } }
至此,我们通过地址:16792/Home/Index访问,整个请求的开始、执行、资源释放就基本结束。现在回过头来理解这个原理,你觉得还难吗~~
4、向Swift.MVC里面加入Model如果你还嫌上述例子太简单,我们可以来个稍微复杂点的例子。我们向测试项目里面引入jquery、bootstrap等组件,添加Models文件夹,向下面加入User.cs
namespace MyTestMVC.Models { public class User { public int Id { get; set; } public string UserName { get; set; } public int Age { get; set; } public string Address { get; set; } public string Remark { get; set; } } }
然后我们向HomeController里面另一个Action定义如下:
public void BootstrapTest() { var lstUser = new List<User>(); lstUser.Add(, Age = , Remark = }); lstUser.Add(, Age = , Remark = }); lstUser.Add(, Age = , Remark = }); lstUser.Add(, Age = , Remark = }); lstUser.Add(, Age = , Remark = }); string strUser = string.Empty; foreach (var oUser in lstUser) { strUser += + oUser.Id + + oUser.UserName + + oUser.Age + + oUser.Address + + oUser.Remark + ; } HttpContext.Current.Response.Write(@" <html> <head> <link href='/Content/bootstrap/css/bootstrap.min.css' /> <script src='/Content/jquery-1.9.1.min.js'></script> <script src='/Content/bootstrap/js/bootstrap.min.js'></script> </head> <body> <div> <div> <div>bootstrap表格</div> <div> <table> <thead> <tr> <th>用户ID</th> <th>用户名</th> <th>年龄</th> <th>地址</th> <th>备注</th> </tr> </thead> <tbody> " + strUser + @" </tbody> </table> </div> </div> </div> </div> </body> </html>");
得到结果:
按照MVC的机制,我们的Swift.MVC里面“M”和“C”都有了,就差“V”了,等有时间我们也来封装一个自己的“V”。
三、版本三:加入自己的路由模块有了第二个版本的支持,博主已经对MVC的原理有了一个清晰的认识。在第三个版本里面,博主打算不用System.Web.Routing里面的属性和方法,完全自己去解析请求,封装上下文,执行MVC,这样才算是真正意义上自己的MVC。考虑到篇幅的问题,也给博主一些准备时间,第三个版本留在下篇发,有兴趣的园友可以先看看版本二,如果你能透彻理解版本二里面的原理,相信你对MVC 已经有一个清晰的认识了。
四、总结