回到目錄

模塊化

這個(gè)問題是在做模塊化設(shè)計(jì)時(shí)出現(xiàn)的,在Lind.DDD.Plugins模塊里,需要對(duì)應(yīng)的模塊實(shí)體,模塊管理者,模塊標(biāo)識(shí)接口等,開發(fā)時(shí),如果你的功能點(diǎn)屬于一個(gè)模塊,需要實(shí)現(xiàn)IPlugins,而當(dāng)實(shí)現(xiàn)了標(biāo)識(shí)接口后,在應(yīng)用程序啟動(dòng)時(shí),會(huì)一次性將所有插件模塊注冊(cè)到你的系統(tǒng)里,在需要使用時(shí),只要使用PluginManager管理者把對(duì)應(yīng)的模塊取出來即可,這個(gè)取出的過程是沒有性能損耗的,它并不是反射!

更多Lind.DDD.Plugins的相關(guān)知識(shí),請(qǐng)閱讀大叔這篇文章《Lind.DDD.Plugins~插件模式的集成

模塊化在UI層的體現(xiàn)

本文主要問題是在設(shè)計(jì)出多個(gè)模塊是,在UI層如何根據(jù)選中的模塊,渲染出不同的VIEW來,這個(gè)問題不是新技術(shù),只需要使用Html.Partial這個(gè)擴(kuò)展方法即可以實(shí)現(xiàn),而大叔要說的是,我們?cè)O(shè)計(jì)模塊時(shí),應(yīng)該把所有模塊放在一個(gè)統(tǒng)一的目錄,新來的模塊View只要放到module即可,由于模塊核心內(nèi)容都寫在對(duì)應(yīng)的module中,controller/action變得更加輕薄,這時(shí),我們很容易使用autofac這些IoC工具把需要的模塊對(duì)象動(dòng)態(tài)生產(chǎn)出來,這也是Lind.DDD.Plugins要做的事情,只不過,為了性能考慮,我們?cè)诔绦騿?dòng)時(shí)已經(jīng)把所有模塊注冊(cè)了,對(duì)于核心業(yè)務(wù)的action,所有模塊共用一個(gè)即可,如列表action使用Index,添加action使用Create,而controller我們使用比較公用的名稱,如商品管理Product,訂單管理Order,而具體的手機(jī)項(xiàng)目product和order及PC端的product和order完全在對(duì)應(yīng)的module里去實(shí)現(xiàn)(邏輯上的實(shí)現(xiàn)),而它們的action只會(huì)路由的轉(zhuǎn)發(fā),即根據(jù)項(xiàng)目去選擇渲染哪一個(gè)View。

WEB MVC下面Module的組成

程序啟動(dòng)時(shí)注冊(cè)Module這個(gè)特殊的路由模塊,讓我們的mvc程序可以找個(gè)Module下面的Views,這個(gè)只對(duì)需要有具體Action時(shí)用,如果你的module只有view,action都有公用模塊實(shí)現(xiàn)了,就不需要注冊(cè)下面代碼了!

復(fù)制代碼
 /// <summary> /// 注冊(cè)模塊 /// </summary> public class Module_routing : RazorViewEngine
    { public Module_routing()
        { //視圖位置 ViewLocationFormats = new[]
            { "~/Views/{1}/{0}.cshtml", "~/Views/Module/{1}/{0}.cshtml" }; //分部視圖位置 PartialViewLocationFormats = new[]
            { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/Views/Module/Shared/{0}.cshtml", "~/Views/Module/{1}/{0}.cshtml" };
        } public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        { return base.FindView(controllerContext, viewName, masterName, useCache);
        } public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        { return base.FindPartialView(controllerContext, partialViewName, useCache);
        }
    }
復(fù)制代碼

在程序啟動(dòng)時(shí),把它的實(shí)例注冊(cè)進(jìn)來

復(fù)制代碼
 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            RegisterView_Custom_routing();
        } protected void RegisterView_Custom_routing()
        {
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new Module_routing());
        }
復(fù)制代碼

而在公用的action里,一般來說,會(huì)接收一個(gè)moduleName或者M(jìn)oduleId這種屬性,然后生產(chǎn)對(duì)應(yīng)的模塊對(duì)象,把對(duì)象的結(jié)果傳給對(duì)應(yīng)的View即可。

       public ActionResult Index(string module)
        { var model=Plugins.PluginManager.Resolve<IShop>("module").GetModel();//這個(gè)地方不是反射,只是從容器里把對(duì)應(yīng)的實(shí)例取出來 return View(model);
        }

在主View上進(jìn)行渲染對(duì)應(yīng)項(xiàng)目的PartialView,同時(shí)把Model傳給對(duì)應(yīng)的View,一般代碼如下

復(fù)制代碼
<ul>
    <li>@Html.ActionLink("pc端", "index", new { module = "pc" })</li>
    <li>@Html.ActionLink("h5端", "index", new { module = "h5" })</li>
    <li>@Html.ActionLink("pad端", "index", new { module = "pad" })</li>

</ul> @Html.Partial("~/views/module/"+Request.QueryString["module"] + "/index.cshtml",Model) <!-- 渲染對(duì)應(yīng)的模塊下的頁面,Model由公用action返回 -->
復(fù)制代碼

這樣產(chǎn)生的好處就是,當(dāng)你添加新的module時(shí),只需要維護(hù)對(duì)應(yīng)的Project即可,然后把主網(wǎng)站的Views/Module文件夾更新,同時(shí)在module數(shù)據(jù)表中添加新的模塊,就實(shí)現(xiàn)的新模塊對(duì)老項(xiàng)目的集成!這一切可以說與原項(xiàng)目是解耦合的,它們可以在不同的解決方案中完成,各自負(fù)責(zé)各位的業(yè)務(wù)邏輯!