回到目錄
子產品化
這個問題是在做子產品化設計時出現的,在Lind.DDD.Plugins子產品裡,需要對應的子產品實體,子產品管理者,子產品辨別接口等,開發時,如果你的功能點屬于一個子產品,需要實作IPlugins,而當實作了辨別接口後,在應用程式啟動時,會一次性将所有插件子產品注冊到你的系統裡,在需要使用時,隻要使用PluginManager管理者把對應的子產品取出來即可,這個取出的過程是沒有性能損耗的,它并不是反射!
更多Lind.DDD.Plugins的相關知識,請閱讀大叔這篇文章《Lind.DDD.Plugins~插件模式的內建》
子產品化在UI層的展現
本文主要問題是在設計出多個子產品是,在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跨平台社群,支援善友大牛!
作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980
支付寶掃一掃,為大叔打賞!
