分享一款基於asp.net mvc框架開發的社區產品--近乎。目前可以在官網免費下載,下載地址:http://www.jinhusns.com/Products/Download?type=whp 1 引言 1.1 目的 用於社會化開發平臺的架構設計指導,闡述基礎設施及關鍵技術構件、業務構件的設計思 ...
分享一款基於asp.net mvc框架開發的社區產品--近乎。目前可以在官網免費下載,下載地址:http://www.jinhusns.com/Products/Download?type=whp
1 引言
1.1 目的
用於社會化開發平臺的架構設計指導,闡述基礎設施及關鍵技術構件、業務構件的設計思想及具體實現。
讀者包括但不限於社會化開發平臺的研發人員,使用社會化開發平臺的產品定製人員以及公司外部的二次開發者。
1.2 參考資料
《架構使用說明書》
《業務使用說明書》
《皮膚設計機制》
1.3 引用術語與縮寫解釋
縮寫、術語 |
解釋 |
多租戶模式 |
產品中存在諸多業務邏輯相同但是使用者數據需要相互隔離的服務(可能是業務構件也可能是應用),採用多租戶模式可以使這類服務獲得重用,從而簡化開發。租戶類型是指一類租戶(例如:群組),租戶是指租戶類型的一個特定實例(例如:群組A)。 |
2 “平臺+應用”設計思想
2.1 設計思想
2.1.1 目的
-
開發架構清晰,易於維護;
-
提升開發效率;
-
提升產品的可擴展性;
-
什麼是應用?
2.1.2 概念
應用指產品中的功能模塊,具有以下特征:
1) 具有一定獨立性的完整的功能模塊;
2) 可以在產品中安裝、卸載、禁用/啟用;
3) 可以在呈現區域安裝、卸載(如果允許在呈現區域安裝);
4) 應用可以設置為鎖定狀態,鎖定的應用不允許卸載(可以禁用);
-
什麼是呈現區域?
呈現區域之間彼此隔離,具有獨立性,可以有獨立的皮膚設計規約及導航,皮膚都是針對呈現區域進行設計的,呈現區域可以看作多個應用數據的容器。頻道、用戶空間、群組空間、後臺,都是呈現區域,都可以定義自己的皮膚及導航。
-
什麼是呈現區域實例?
是指呈現區域在運行期間生成的一個具體可以使用的實例,呈現區域分為單例和多例,每個呈現區域實例都有自己的Owner。例如:
1) 頻道、後臺屬於單例:Owner=0;
2) 用戶空間、群組空間屬於多例:Owner為UserId或GroupId;
-
應用與呈現區域的關係
1) 1個應用可以在多個呈現區域中使用,可以為不同的呈現區域提供數據;
2) 1個呈現區域下,可以有多個應用,為應用數據提供統一的導航及皮膚設計;
2.1.3 設計要點
圖表1應用設計整體設想
-
應用應該保持獨立性:
1) 應用設計在物理上、邏輯上儘量獨立;
2) 儘量避免應用之間的依賴;
-
應用的設計主要包括兩部分的內容,一部分是數據另一部分是如何呈現;
-
應用的數據部分支持多租戶,租戶可以是呈現區域(PersentArea)也可以是另一個應用。
2.1.3.1 數據部分
在資料庫設計方面採用最簡單的方式,在應用數據表中增加TenantTypeId(存儲對應的PersentAreaKey或ApplicationId)。
2.1.3.2 呈現部分
按照當前的皮膚設計機制,應用的View僅有一份(在所有皮膚中共用),而導航等UI元素的風格又經常會在不同皮膚中進行調整,因此必須把這一部分UI元素交由平臺部分進行設計,各應用僅對外公佈呈現這部分UI元素的數據。基於這個原因,需要抽象出來的UI元素包括:導航、管理菜單、快捷操作,這幾個UI元素在不同的呈現區域各不相同因此應該重新設計。
2.2 設計實施
2.2.1 設計規則
-
應用可以由開發者設置為鎖定狀態,鎖定狀態的應用不允許刪除(可以禁用);
-
應用在呈現區域可以設置為內置應用:
1) 內置應用不允許卸載;
2) 內置應用屬於自動安裝應用(無論自動安裝屬性設置何值);
-
應用在呈現區域可以設置為自動安裝:創建呈現區域實例時,自動安裝到該呈現區域中;
-
在站點安裝/卸載(目前僅考慮手動進行安裝/卸載)時需要添加/移除以下數據:
2.2.2 安裝/卸載
1) tn_Applications:應用表;
2) tn_ApplicationInPresentAreaSettings:應用在呈現區域的設置;
3) tn_InitialNavigations:應用在呈現區域的初始化導航;
4) tn_ApplicationManagementOperations:應用在呈現區域的管理操作;
-
在呈現區域安裝/卸載(由呈現區域實例Owner在管理界面執行)時需要添加/移除以下數據:
1) tn_ApplicationInPresentAreaInstallations:應用在呈現區域的安裝記錄;
2) tn_PresentAreaNavigations:呈現區域實例的導航數據;
3) 應用數據中與該呈現區域實例相關的數據(卸載時需要考慮);
-
在其他應用安裝/卸載:
1) 當前底層設計支持一個應用安裝在另一個應用中;
2) 由開發者自行完成;
2.2.3 平臺支撐
為了最大限度提升應用的開發效率,把應用開發常用的代碼封裝成可重用的技術構件(Infrastructure)和業務構件(BusinessComponents)。
圖表2平臺+應用詳細視圖
3 應用開髮指導
3.1 開發流程概覽
3.2 建立應用的目錄結構
3.2.1 手動建立
您可以手動的建立您的應用目錄結構:
-
在Web/Applications/建立以應用的ApplicationKey命名的Web Application;
-
在Web/Applications/{ApplicationKey}/建議包含以下目錄結構:
圖表1應用模塊目錄結構
3.2.2 自動建立
您還可以使用我們提供的AppHelper程式來自動生成目錄結構。點擊附件進行下載:[attach:2818]
圖表2 AppHelper
3.3 開發必需的程式代碼
-
從ApplicationBase派生自己的Application類,必須實現以下方法:
方法名稱 |
成員修飾 |
說明 |
備註 |
Install(string presentAreaKey, long ownerId):bool |
internal protected |
為呈現區域實例安裝應用 |
|
UnInstall(string presentAreaKey, long ownerId):bool |
internal protected |
為呈現區域實例卸載應用 |
|
DeleteUser(long userId, string reassignContentToUserName = null):void |
internal protected |
刪除用戶在應用中的數據 |
|
-
從ApplicationConfig派生自己的應用配置類,必須重寫以下屬性:
屬性名稱 |
成員修飾 |
說明 |
備註 |
ApplicationId : int |
public |
該應用的ApplicationId |
|
ApplicationKey : string |
public |
該應用的ApplicationKey |
|
-
定義UrlRoutingRegistration.cs
1) 從System.Web.Mvc.AreaRegistration派生;
2) 使用ApplicationKey作為AreaName;
-
如果需要則創建Application.config;
圖表3開發應用需要實現的抽象類
3.4 配置應用
-
創建應用(涉及到tn_Applications表)
欄位名稱 |
欄位描述 |
日誌應用配置示例 |
ApplicationId |
應用Id 要求全局唯一,第三方應用建議從3001開始 |
1002 |
ApplicationKey |
Application英文唯一標識 |
Blog |
Description |
應用描述 |
N’’ |
IsEnabled |
是否啟用 不啟用的應用,在前臺各呈現區域中,不會顯示 |
1 |
IsLocked |
是否鎖定 目前版本暫時用不到 |
0 |
-
分析應用和呈現區域(涉及到tn_ApplicationInPresentAreaSettings表)
分析該應用可能會在那些呈現區域中使用,是否允許用戶安裝或卸載,是否為用戶自動安裝應用,是否會產生數據。具體配置說明如下:
欄位名稱 |
欄位描述 |
ApplicationId |
應用Id |
PresentAreaKey |
呈現區域標識 |
IsBuiltIn |
是否為呈現區域內置應用 內置應用會預設創建,並且不允許卸載 |
IsAutoInstall |
是否在呈現區域自動安裝 |
IsGenerateData |
應用在該呈現區域是否產生數據 |
日誌配置示例如下:
tn_ApplicationInPresentAreaSettings |
||||
ApplicationId |
PresentAreaKey |
IsBuiltIn |
IsAutoInstall |
IsGenerateData |
1002 |
N'Channel' |
0 |
1 |
0 |
1002 |
N'UserSpace' |
0 |
1 |
1 |
-
導航
分析應用在各個呈現區域會有哪些導航,導航的鏈接地址、圖標會是什麼,是否在新窗打開,具體配置說明如下:
欄位名稱 |
欄位描述 |
NavigationId |
定義規則:[呈現區域Id:2位][應用Id:4位][ 順序號:N位] 呈現區域Id包括:10(頻道)、11(用戶空間)、13(群組空間)、20(後臺); 應用ID若不足四位,請用零左補齊;必須唯一; |
ParentNavigationId |
父導航Id 一級導航,請填寫0; |
Depth |
深度(從上到下以0開始) |
PresentAreaKey |
呈現區域標識 可選值:N'Channel'(頻道)、N'UserSpace'(用戶空間)、N'GroupSpace'(群組空間)、N'ControlPanel'(後臺) |
ApplicationId |
應用Id |
NavigationType |
導航類型 可選值:0(來源於Application)、1(呈現區域初始化的導航)、2(呈現區域Owner新增的導航) 應用初始化數據中,請填寫0 |
NavigationText |
導航文字 |
ResourceName |
導航文字資源名稱(如果同時設置NavigationText則以NavigationText優先) 此項比配置導航文字的優勢之處在於,方便實現國際化 |
NavigationUrl |
導航url,如果是來源於應用,並且該欄位為空,則根據UrlRouteName獲取 通過後臺添加外鏈時,可使用此項 |
UrlRouteName |
應用導航路由規則名稱將會根據該規則名稱獲取應用導航地址 在應用初始化數據中,請使用UrlRouteName獲取導航地址 |
RouteDataName |
路由數據名稱 使用UrlRouteName欄位時,此項才有效 |
IconName |
系統內置圖標名稱 |
ImageUrl |
菜單文字旁邊的圖標url(預留欄位,暫時用不到) |
NavigationTarget |
是新開視窗還是在當前視窗(預設:_self) |
DisplayOrder |
排序序號 建議和導航Id保持一致 |
OnlyOwnerVisible |
是否僅擁有者可見 |
IsLocked |
是否鎖定
|
IsEnabled |
是否啟用 |
日誌配置示例如下:
tn_InitialNavigations |
||||||
欄位名稱 |
頻道日誌 一級導航示例 |
頻道日誌 二級導航示例 |
頻道日誌 二級導航示例2 |
用戶空間日誌 一級導航示例 |
用戶空間日誌 二級導航示例 |
後臺日誌 導航示例 |
NavigationId |
10100201 |
10100202 |
10100203 |
11100201 |
11100202 |
20100201 |
ParentNavigationId |
0 |
10100201 |
10100201 |
0 |
11100201 |
20000011 |
Depth |
0 |
1 |
1 |
0 |
1 |
2 |
PresentAreaKey |
N'Channel' |
N'Channel' |
N'Channel' |
N'UserSpace' |
N'UserSpace' |
N'ControlPanel' |
ApplicationId |
1002 |
1002 |
1002 |
1002 |
1002 |
1002 |
NavigationType |
0 |
0 |
0 |
0 |
0 |
0 |
NavigationText |
N'日誌' |
N'日誌首頁' |
N'我的日誌' |
N'日誌' |
N'日誌首頁' |
N'日誌' |
ResourceName |
N'' |
N'' |
N'' |
N'' |
N'' |
N'' |
NavigationUrl |
N'' |
N'' |
N'' |
N'' |
N'' |
N'' |
UrlRouteName |
N'Channel_Blog_Home' |
N'Channel_Blog_Home' |
N'UserSpace_Blog_Blog' |
N'UserSpace_Blog_Home' |
N'UserSpace_Blog_Home' |
N'ControlPanel_Blog_Home' |
RouteDataName |
NULL |
NULL |
N'spaceKey' |
NULL |
NULL |
NULL |
IconName |
N'Blog' |
NULL |
NULL |
N'Blog' |
NULL |
NULL |
ImageUrl |
NULL |
NULL |
NULL |
NULL |
NULL |
NULL |
NavigationTarget |
N'_self' |
N'_self' |
N'_self' |
N'_self' |
N'_self' |
N'_self' |
DisplayOrder |
10100201 |
10100202 |
10100203 |
11100202 |
11100202 |
20100201 |
OnlyOwnerVisible |
0 |
0 |
0 |
1 |
1 |
0 |
IsLocked |
0 |
0 |
0 |
0 |
0 |
0 |
IsEnabled |
1 |
1 |
1 |
1 |
1 |
1 |
-
管理操作
欄位名稱 |
欄位描述 |
OperationId |
定義規則:[呈現區域Id:2位][應用Id:4位][ 順序號:N位] 呈現區域Id包括:10(頻道)、11(用戶空間)、13(群組空間)、20(後臺); 應用ID若不足四位,請用零左補齊;必須唯一; |
ApplicationId |
應用Id |
AssociatedNavigationId |
關聯的導航Id(適用於顯示在主導航旁邊的快捷操作,例如我的首頁左側的相冊導航,可以在其旁邊再加一個“上傳”快捷操作) |
PresentAreaKey |
呈現區域標識 |
OperationType |
管理操作類型 可選值:1(快捷操作)、2(管理菜單) |
OperationText |
操作的文字 |
ResourceName |
操作文字資源名稱(如果同時設置OperationText則以OperationText優先) |
NavigationUrl |
導航url |
UrlRouteName |
導航路由規則名稱 |
RouteDataName |
路由數據名稱 |
IconName |
系統內置圖標名稱 |
ImageUrl |
菜單文字旁邊的圖標url(預留欄位,暫時用不到) |
NavigationTarget |
是新開視窗還是在當前視窗(預設:_self) |
DisplayOrder |
排序序號 |
OnlyOwnerVisible |
是否僅擁有者可見 |
IsLocked |
是否鎖定
|
IsEnabled |
是否啟用 |
日誌配置示例如下:
欄位名稱 |
頻道日誌 一級導航示例 |
頻道日誌 二級導航示例 |
OperationId |
10100201 |
11100201 |
ApplicationId |
1002 |
1002 |
AssociatedNavigationId |
0 |
0 |
PresentAreaKey |
N'Channel' |
N'UserSpace' |
OperationType |
1 |
1 |
OperationText |
N'撰寫日誌' |
N'撰寫日誌' |
ResourceName |
N'' |
N'' |
NavigationUrl |
N'' |
N'' |
UrlRouteName |
N'UserSpace_Blog_Create' |
N'UserSpace_Blog_Create' |
RouteDataName |
N'spaceKey' |
NULL |
IconName |
N'Write' |
N'Write' |
ImageUrl |
NULL |
N'' |
NavigationTarget |
N'_blank' |
N'_self' |
DisplayOrder |
10100202 |
11100201 |
OnlyOwnerVisible |
1 |
1 |
IsLocked |
0 |
1 |
IsEnabled |
1 |
1 |
3.5 開發必須的SQL腳本
-
安裝腳本:需要考慮以下表的初始化數據:
1) tn_Applications:應用表;
2) tn_ApplicationInPresentAreaSettings:應用在呈現區域的設置;
3) tn_InitialNavigations:應用在呈現區域的初始化導航;
4) tn_ApplicationManagementOperations:應用在呈現區域的管理操作;
-
卸載腳本:
1) 清除安裝時添加的數據;
2) tn_ApplicationStatisticalData:應用統計數據;
3) tn_PresentAreaNavigations:應用在呈現區域的導航數據;
4) 以及應用自身的數據;
-
升級腳本:由開發者根據應用情況自行設計;
4 高級應用
4.1 界面融合
要達到和現有皮膚整體風格保持一致,應用頁面就需要使用預置的佈局,具體說明如下:
a) 頻道佈局包括:app-1col.cshtml(通欄佈局)、app-home-2cols.cshtml(應用首頁兩欄佈局)、app-home-3cols.cshtml(應用首頁三欄佈局)、app-list-2cols.cshtml(應用列表兩欄佈局)、app-detail-2cols.cshtml(應用詳情兩欄佈局)、app-form-2cols.cshtml(應用表單兩欄佈局);
b) 群組佈局包括:app-1col.cshtml(通欄佈局)、app-list-2cols.cshtml(應用列表兩欄佈局)、app-detail-2cols.cshtml(應用詳情兩欄佈局)、app-form-2cols.cshtml(應用表單兩欄佈局)、app-outer-home-2cols.cshtml(對外顯示時,應用首頁兩欄佈局);
c) 用戶空間佈局包括:app-1col.cshtml(通欄佈局)、app-list-2cols.cshtml(應用列表兩欄佈局)、app-detail-2cols.cshtml(應用詳情兩欄佈局)、app-form-2cols.cshtml(應用表單兩欄佈局)、app-outer-home-2cols.cshtml(對外顯示時,應用首頁兩欄佈局);
4.2 使用業務構件與平臺深度開發
常用到的業務構件有:審核、動態、通知、積分、許可權,具體請參見《業務構件使用說明書》
4.3 擴展新視頻、音樂網站解析插件
-
視頻網站解析插件:
a) 在~/Plugins/MediaParsers/Video/目錄下,創建View文件,並以視頻網站的功能變數名稱關鍵詞(保證功能變數名稱中包含該關鍵詞,並與其它視頻網站解析插件名不同即可)命名;
b) 編輯View文件,實現以下邏輯:
i. 匹配該視頻網站的視頻詳細頁面地址,匹配成功則繼續以下操作;
ii. 抓取頁面內容,分析出視頻名稱、視頻播放地址、視頻縮略圖、視頻描述,並構建ParsedMedia實體,保存至資料庫;
iii. 輸出ParsedMedia實體的Json格式。
-
音樂網站解析,與視頻網站解析類似。
4.4 使用ORM、緩存快速開發數據訪問
參見《架構使用說明書》4.1之前版本[attach:2818]4.2版本[attach:5180]