3.Magicodes.NET框架之路——預覽(一)
-
前言
一眨眼,已經過去兩個多月了 ,哥已經火力全開了(業余時間和精力,甚至為此放棄了各種私活),所以大家不要抱怨慢哈。編程猶如逆水行舟,不進則退。這段時間,一方面是不斷地重構和設計框架,另一方面也系統的學習了很多新技術,同時也感受到了其強大的生命力。
所以這兩個多月,也感慨良多。兩個多月的業余時間和精力,兩個多月沒玩LOL和CF,兩個多月的全身心投入……
現在本篇就重點說說架構這些事:
-
架構多次重構,甚至核心模塊多次推倒重來。
-
架構已支持MVC,不過卻暫時放棄了WebForm,當然也有可能永久放棄WebForm,畢竟我目前只是一個人在戰斗,兼容兩套時間精力都極為有限。
-
引入了T4,已支持基於T4模板的代碼生成。
-
已支持SignalR。
-
已支持ASP.NET Identity以及集成 OAuth(Microsoft、QQ、Google…),暫時移除了對Form驗證的支持。
-
支持WebAPI和Odata。
-
前端框架初成,支持響應式布局以及MVVM模式和模塊化加載。
-
其他
接下來,我一一簡單的介紹下本框架好了。
首先,先從前端開始介紹吧:
-
響應式布局的UI
后台:
其他設備(為了用戶體驗,后台框架使用了Iframe,在其他設備上訪問時,可能多少會有些問題):
還有個列表頁面,但是更改為MVC后,還沒來得及改好。
前台:
-
模塊化按需加載
前端JS寫了一部分,但是感覺還遠遠達不到完善的級別。很希望哪位前端工程師能夠給予支持,這樣我的重心就更好的放到后端架構上了。
在JS的選擇上,最終選擇了優秀的RequireJs,一直用下來,感覺比SeaJs更完善,更好用和更易用。
先看幾段Demo,比如登錄頁面:
Magicodes.js做了不少封裝,當然是為了最大限度的節省生產力。整個登錄機制就是以上腳本搞定,當然還與MVVM有關聯,這個是下面要介紹的。
Magicodes.js為目前的前端框架核心庫,當然目前還稱不上庫。其內部很多模塊也都是按需加載的,比如:
window.magicodes.messager = {
showMessage: function (title, message, className, funcs) {
var setting = {
title: title,
text: message,
class_name: className
};
if (typeof (funcs) !== "undefined") {
if (typeof (funcs.before_close) !== "undefined")
setting.before_close = funcs.before_close;
if (typeof (funcs.after_open) !== "undefined")
setting.after_open = funcs.after_open;
}
this._addGritter(setting);
},
showInfoMessage: function (title, message, funcs) {
this.showMessage(title, message, 'gritter-info gritter-light', funcs);
},
showErrorMessage: function (title, message, funcs) {
this.showMessage(title, message, 'gritter-error gritter-light', funcs);
},
showWarnMessage: function (title, message, funcs) {
this.showMessage(title, message, 'gritter-warning gritter-light', funcs);
},
removeAll: function () {
typeof ($.gritter) !== "undefined" && $.gritter.removeAll();
},
_addGritter: function (setting) {
require(["jquery", "jquery.gritter"], function () {
$.gritter.add(setting);
});
}
};
這個是彈出消息的,如:
這里就不多說了。
-
MVVM
在MVVM框架的選擇上,最終選擇了knockoutjs。主要是夠輕量級,也夠靈活。用下來,感覺相當不錯。
比如登錄頁面:
登陸頁面這個比較簡單,重點是導航的綁定,馬上給大家秀一段。
按照傳統的方式來開發如下圖所示的功能,少不了遞歸綁定(支持多級),一堆的JS控制,一堆的業務代碼(其實開始我也是寫代碼的,后面才改為了MVVM模式,走彎路了,呵呵)
那么現在是怎么做到的呢?如下面代碼:
也就是我的綁定邏輯已經脫離了數據模型,前台顯示我只需要改動這段代碼即可。是不是很強悍呢?
然后JS只要給到數據即可。后台從WebAPI拿到如下JSON:
然后JS處理下,根據父子關系,生成children屬性(方便視圖綁定):
//添加菜單子項
//源數據
//當前項
this._appendChildrenMenus = function (data, itemData) {
var childrenNavs = $.grep(data, function (i) {
return i.ParentId == itemData.Id;
});
if (childrenNavs.length > 0) {
itemData.children = childrenNavs;
$.each(childrenNavs, function (i, v) {
v._active = ko.observable(false);
v._open = ko.observable(false);
self._appendChildrenMenus(data, v);
});
}
};
核心代碼主要如下:
使用knockoutjs是不是很方便呢?其實knockoutjs很不錯,除了這些,knockoutjs可以干很多很便捷的事情,比如綁定分頁,綁定列表,綁定表單,這里只是做一些列舉,后面開貼細講,畢竟knockoutjs的實例還是比較少的。
這里再付一個分頁的模板:
<script id="pagesTemplate" type="text/html">
<li class="prev" data-bind="css: { disabled: $root.gridViewModel.currentPageIndex() <= 1 }, click: function () { $root.previousPage(); }">
<a href="#">
<i class="ace-icon fa fa-angle-double-left"></i>
</a>
</li>
<!-- ko foreach: $root.gridViewModel.pages -->
<li data-bind="css: { active: $data == $root.gridViewModel.currentPageIndex() }"><a href="#" data-bind=" text: $data, click: function () { $root.gridViewModel.currentPageIndex($data); } "></a></li>
<!-- /ko -->
<li class="next" data-bind="css: { disabled: $root.gridViewModel.currentPageIndex() >= $root.getTotalPages() }, click: function () { $root.nextPage(); }">
<a href="#">
<i class="ace-icon fa fa-angle-double-right"></i>
</a>
</li>
</script>
前端的先就介紹到這里吧,期待前端工程師的加入,讓我們一起來打造Magicodes前端框架。
現在,來說說后台框架吧:
-
插件式架構
如下圖,這是目前的項目結構。
視圖頁、控制器、策略、數據模型、Service(含WebApi和Odata)均以插件存在。
在我這里,Service插件和傳統的層有很大區別。我這里的Service組件側重與WebApi和Odata提供的Web接口。
-
MVC
目前已經移除了 對WebForm的支持,正所謂有了老婆忘了娘。嘿嘿。
注意:配置管理的所有配置視圖和控制器使用了T4模板自動生成。這個下面會介紹。
-
ASP.NET Identity 和OAuth
Magicodes.NET支持 ASP.NET Identity以及OAuth協議,在不編寫一行代碼的情況下,您就可以便捷的集成QQ、Microsoft、Google、Facebook、Twitter等OAuth接口。
后面還會支持更多…
-
WebAPI
曾經我也設計了一套WebAPI,目前已經移除了對此API的支持。改為基於微軟的WebAPI進行封裝。從一接觸WebAPI就喜歡上它了,毋庸置疑,她將來的成就會不可限量。這里簡單的介紹下:
比如剛才看到的站點信息配置頁面,其WebAPI如下:
這里很明顯的是一套基於REST協議標准的Web方法。WebAPI並不一定必須基於REST協議來設計哈,只是推薦而已。
Get、Post、Put,其實還有Delete(這里因為配置文件不能刪除),這是Rest協議標准的Web方法。一流公司制定標准,我們要抓緊抱佛腳。不要認為標准離我們很遠,你不去擁抱,人家能主動過來么?
先介紹下REST協議,代表性狀態傳輸(Representational State Transfer,REST)在 Web 領域已經得到了廣泛的接受,是基於 SOAP 和 Web 服務描述語言(Web Services Description Language,WSDL)的 Web 服務的更為簡單的替代方法。接口設計方面這一轉變的關鍵證據是主流 Web 2.0 服務提供者(包括 Yahoo、Google 和 Facebook)對 REST 的采用,這些提供者棄用或放棄了基於 SOAP 和 WSDL 的接口,而采用了更易於使用、面向資源的模型來公開其服務。
也順便多說點。REST 要求開發人員顯式地使用 HTTP 方法,並且使用方式與協議定義一致。這個基本 REST 設計原則建立了創建、讀取、更新和刪除(create, read, update, and delete,CRUD)操作與 HTTP 方法之間的一對一映射。根據此映射:
-
若要在服務器上創建資源,應該使用 POST 方法。
-
若要檢索某個資源,應該使用 GET 方法。
-
若要更改資源狀態或對其進行更新,應該使用 PUT 方法。
-
若要刪除某個資源,應該使用 DELETE 方法。
我前面為什么說WeAPI會爆發出強大的生命力?是因為之前的WebServices也好,還是SOAP等接口已經不滿足現有的使用場景了。很多時候,我們的接口內容得看什么終端輸出什么,就如見什么人說什么話一樣。看見Html調用,給他JSON就好了,C#、Java客戶端調用,就給他返回XML讓他去玩好了,MongoDB也要玩,給他BSON就好了。還有不支持的?自己定義好了。總之,程序員們放心了,接口要支持新的平台,我們啥都不需要干了。我們也不需要維護多套代碼了。這是多么Happy的事情呀。當然返回什么,是HTTP Accept Header決定的。
我們讓他返回JSON
他就乖乖的返回了JSON:
讓他返回XML,他就乖乖返回了XML:
上面只是增改查的例子,下面再來一個查詢的例子,比如獲取導航菜單:
//Get /api/Menus
/// <summary>
/// 獲取用戶當前的菜單項
/// </summary>
/// <returns></returns>
public IHttpActionResult Get()
{
var userId = User.Identity.GetUserId();
var menus = from link in db.MenuLinks
where
!link.IsDelete &&
link.Roles.Any(p => db.Users.FirstOrDefault(p1 => p1.Id == userId).Roles.Any(p2 => p2.RoleId == p.Id))
select link;
return Ok(menus);
}
好了,這個就說到這里。繼續下面的:
-
T4以及代碼生成
Magcodes.NET一個比較重要的理念是高效開發,那么代碼生成肯定少不了。
以前玩過CodeSmith,但是現在感覺T4真他娘的比CodeSmith方便多了。Magcodes.NET制作了不少T4模板,旨在盡可能的減少代碼的編寫。這里就舉一個例子:
比如下面看到的配置界面,包括后台信息配置、郵箱信息配置等等界面,從View到WebAPI均是生成的,不需要手寫代碼。
如何生成的呢?我們來看看相關的生成View的T4模板的片段吧(具體的這里就不介紹了):
后面我會專門寫一篇隆重介紹Magicodes.NET使用T4模板生成的,按照我的設想,將來代碼生成遠不止如此。
-
尾聲
今天就介紹到這里吧,寫這個也蠻費時間的。累哈。還有些東西,就下篇再介紹吧:
-
OData以及增刪改查
-
T4 & 增刪改查
-
路由系統
-
配置管理
-
事件管理
-
SignalR
-
Code First與基於代碼的遷移
-
日志與監控
-
后台控制
-
… …
代碼還在不斷更改中,所以最新版下載並不能夠隨時放出,因為目前的版本還不夠穩定,請大家體諒。一旦穩定版出來,我會第一時間提供下載。
另外,也希望有興趣的小伙伴能夠參與進來,按照我的規划,還有不少任務需要完成,比如:
-
社區與博客搭建
-
各種業務的T4模板編寫
-
流程引擎
-
ASP.NET服務監控模塊
-
通用的支付策略
-
其他
人力有時窮,畢竟一個人的精力有限,而且我的主要精力目前還得圍繞框架轉,如果你有興趣和時間,請加入我們。
很多模塊並沒有開發完或者不夠完善,本人精力有限,目前一段時間均會關注在框架這塊,希望業務模塊和前端有朋友能夠幫忙完善完善。
請關注我的官網——http://www.magicodes.net。
另外,Magicodes.NET將提供一個應用實例:官網以及博客社區(目前博客是隨便Down的,但是功能卻不是我想要的),有興趣的可以加入。
由於官網使用了本框架進行了重新開發,所以之前的注冊數據已經丟失,給你們帶來的不便,請諒解。這次之后,應該是不刪檔測試了,建議大家綁定自己的QQ號碼,如果你無法使用QQ登錄,那就說明接口還沒有審核通過,請耐心等待。
最后,分享一首本人前段時間偶有所感而得的詩,雖然還是之前那首:
夏雪
你是一朵特立獨行的雪花
就這么突兀的出現在這個城市的晴空
冰晶的容顏,雪白的羅裙
仿佛整個烈日里都是綻放着的你的美
我只是這個城市的過客
茫然而不知所終
你緩緩飄下,然后又不顧一切地融化在我的手心
你給了我你生命中的所有的絢爛
而我卻是一個過客
也許你不該出現在這個烈烈的晴空
也許我不該行走在這個喧囂的城市
只是,
不知這一刻的邂逅,可是為了那一刻的永恆
感言:夢想總是如雪花般美好但是嬌嫩脆弱,而追求夢想之路就猶如修仙一般逆天而行,如果信念不夠執著,那甚至還做不到曇花一現。雖然現在是"酷暑",但是只要執着,夏雪又何嘗不會成就冬天。