看大牛们的源码,对于水平一般的人,还是略微有点难度的。我从我自身读码的亲身体验,写下杂散片语,希望能和大家一同进步,也为了日后记忆上的备查。

 

  先看的是brnMall的源码结构,从哪看起呢?

 首先推荐看的肯定是官方的剖析:BrnShop开源网上商城第二讲:ASP.NET MVC框架

 官方的这篇文章主要讲清楚了几点:

 (1)brnshop设计时对网页环境上下文是如何获得,如何保存,并如何访问的(重载了控制器的基类,用于截获http访问时的预处理,身份授权和验证等问题),这些都是mvc程序自定义时惯用的方式。

 (2)而为了便利地获得上下文,并自动转换对应类型,则需要重写mvc的WebViewPage页。这里可能一些读者会搞不清楚,这里涉及到对mvc底层的一些了解,我找了些资料看了看,才弄明白。资料url:ASP.NET MVC的Razor引擎:View编译原理

  简单说:一个View最终也被编译成一个类,这个类的基类可以自定义为WebViewPage类的派生类,所以可以在这个派生类里完成上下文的类型转换,并替换为视图页面的基类。当然做自定义替换后,也要记得改相关的配置,让mvc用你自定义的视图页的派生类作为基类来生成页面。

 (3)另外,讲一下,代码阅读时,该代码的划分放置。

    (A) brnMall的Library中的brnMall.Data主要是数据库实体类(和各种表对象打交道),brnMall.Core主要是业务逻辑和辅助功能用到的接口和策略配置管理类(譬如:邮件接口和配置,订单接口和配置),brnMall.Service则是业务逻辑具体的实现

   (B) 阅读变现层Presentatio时,重点是要读懂两点:

   第一:框架上的自定义改造作者是怎么做的,在BrnMall.Web.Framework中,在Controller里对各个主页面模块的控制器基类做了派生,主要在派生类里完成了网页上下文信息的自动记录。这样当用户访问页面首页时,就能自动获取很多信息,譬如:浏览器类型,是否为移动设备的用户等等。在ViewPages里主要是做了对获取的上下文做了类型返回的自动转换。在Pager里主要对分页做了相关处理。在Validator中主要是封装了各种信息的合法性检查的逻辑和正则表达式的使用。而Theme这个主题风格的问题,目前还没深入读,后面再做分析。

   第二:我们看代码时,一般会希望知道程序的起点和跳转的逻辑。我们知道mvc程序都是有启动项目的,BrnMall.Web就是启动项目,在它的Global.asax中为程序的起点。

  

namespace BrnMall.Web
{
    public class BrnMallApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            //将默认视图引擎替换为ThemeRazorViewEngine引擎
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new ThemeRazorViewEngine());

            //注册所有的区域
            /*AreaRegistration.RegisterAllAreas()是global.asax中调用的,它会找到所有的AreaRegistration的子类,
             * 不管是在Web项目中,还是在其他类库项目中。所以我们在项目的Api文件夹中放一个AreaRegistration的子类,
             * 也是能被找到的,然后在注册Area时,在参数中传递Controller所在的命名空间,问题就解决了。
             */
            AreaRegistration.RegisterAllAreas();

            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //启动事件机制
            BMAEvent.Start();
            //服务器宕机启动后重置在线用户表
            if (Environment.TickCount > 0 && Environment.TickCount < 900000)
                OnlineUsers.ResetOnlineUserTable();
        }
    }
}

 在这里启动时,BrnMall做了很多替换和设置,譬如:视图引擎,路由表的注册,这里还有一个重要的设置:AreaRegistration.RegisterAllAreas();

 这句代码的作用是什么呢?它是在同一个解决方案里,不同的项目使用了不同的Areas,区域。而各个项目Area的跳转以及调用方式,都和area和路由的写法有关系。这是什么意思呢?举个例子:如果一个用户拿手机访问BrnMall,它是如何显示页面的呢,它首先在主area里,也就是BrnMall.Web的控制器HomeController的Index方法中

   /// <summary>
    /// 首页控制器类
    /// </summary>
    public partial class HomeController : BaseWebController
    {
        /// <summary>
        /// 首页
        /// </summary>
        public ActionResult Index()
        {
            //判断请求是否来自移动设备,如果是则重定向到移动主题
            if (WebHelper.GetQueryInt("m") != 1 && WebHelper.IsMobile())
                return RedirectToAction("index", "home", new RouteValueDictionary { { "area", "mob" } });

            //首页的数据需要在其视图文件中直接调用,所以此处不再需要视图模型
            return View();
        }
    }

View Code

在这个方法中,判断了上下文是否为移动设备,如果是则跳转到移动项目的Area上的同名控制器的index方法上去。

//判断请求是否来自移动设备,如果是则重定向到移动主题
if (WebHelper.GetQueryInt(“m”) != 1 && WebHelper.IsMobile())
   return RedirectToAction(“index”, “home”, new RouteValueDictionary { { “area”, “mob” } });

这句代码就使用到了如何跳转Area,以及如何定义Area的知识。Area有两种定义方式,一种是在同一个项目中添加Area,另一种是在同一个解决方案的不同项目有不同的Area。

而BrnMall就是第二种结构,他在每一个非主Area,且有界面视图的项目里都有一个文件:AreaRegistration.cs文件,这个文件定义了AreaRegistration类的派生类,在这个派生类里指明了Area的名字和路由方法。最后,在程序的起点再通过调用AreaRegistration.RegisterAllAreas(); 就可以自动找到所有定义的Area和对应的路由方式。这就是另一处需要注意的事情。下面也给出了参考的网上文章。

.NET/ASP.NET MVC(模块化开发AraeRegistration)

今天先写到这吧,下次我们来读读nopCommerce的起点结构分析,有点压力,因为感觉那个代码比较难,尽力吧!

愿意交朋友的可以加我QQ:9200118

 

版权声明:本文为ashacher原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ashacher/p/5655177.html