回到目錄
這個問題是在做模塊化設計時出現的,在Lind.DDD.Plugins模塊裡,需要對應的模塊實體,模塊管理者,模塊標識接口等,開發時,如果你的功能點屬於一個模塊,需要實現IPlugins,而當實現了標識接口後,在應用程序啟動時,會一次性將所有插件模塊注冊到你的系統裡,在需要使用時,只要使用PluginManager管理者把對應的模塊取出來即可,這個取出的過程是沒有性能損耗的,它並不是反射!
更多Lind.DDD.Plugins的相關知識,請閱讀大叔這篇文章《Lind.DDD.Plugins~插件模式的集成》
本文主要問題是在設計出多個模塊是,在UI層如何根據選中的模塊,渲染出不同的VIEW來,這個問題不是新技術,只需要使用Html.Partial這個擴展方法即可以實現,而大叔要說的是,我們設計模塊時,應該把所有模塊放在一個統一的目錄,新來的模塊View只要放到module即可,由於模塊核心內容都寫在對應的module中,controller/action變得更加輕薄,這時,我們很容易使用autofac這些IoC工具把需要的模塊對象動態生產出來,這也是Lind.DDD.Plugins要做的事情,只不過,為了性能考慮,我們在程序啟動時已經把所有模塊注冊了,對於核心業務的action,所有模塊共用一個即可,如列表action使用Index,添加action使用Create,而controller我們使用比較公用的名稱,如商品管理Product,訂單管理Order,而具體的手機項目product和order及PC端的product和order完全在對應的module裡去實現(邏輯上的實現),而它們的action只會路由的轉發,即根據項目去選擇渲染哪一個View。
WEB MVC下面Module的組成
程序啟動時注冊Module這個特殊的路由模塊,讓我們的mvc程序可以找個Module下面的Views,這個只對需要有具體Action時用,如果你的module只有view,action都有公用模塊實現了,就不需要注冊下面代碼了!
/// <summary> /// 注冊模塊 /// </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); } }
在程序啟動時,把它的實例注冊進來
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()); }
而在公用的action裡,一般來說,會接收一個moduleName或者ModuleId這種屬性,然後生產對應的模塊對象,把對象的結果傳給對應的View即可。
public ActionResult Index(string module) { var model=Plugins.PluginManager.Resolve<IShop>("module").GetModel();//這個地方不是反射,只是從容器裡把對應的實例取出來 return View(model); }
在主View上進行渲染對應項目的PartialView,同時把Model傳給對應的View,一般代碼如下
<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) <!-- 渲染對應的模塊下的頁面,Model由公用action返回 -->
這樣產生的好處就是,當你添加新的module時,只需要維護對應的Project即可,然後把主網站的Views/Module文件夾更新,同時在module數據表中添加新的模塊,就實現的新模塊對老項目的集成!這一切可以說與原項目是解耦合的,它們可以在不同的解決方案中完成,各自負責各位的業務邏輯!
感謝各位對大叔框架的支持!
同時希望大家多多支持咱們.Net跨平台社區,支持善友大牛!
回到目錄