Orchard工作原理

来源:http://www.cnblogs.com/anduril/archive/2016/04/20/5412923.html
-Advertisement-
Play Games

概述 本文翻譯僅供學習之用,瞭解Orchard工作原理設計思想、技術點及關鍵詞,如有缺漏請不吝指正。鑒於能力有限定有諸多曲解或不完整的地方,請海涵。不定時完善整理。 CMS不像常規的web程式,它更像一個程式容器。 設計系統時採用一個開放類型的架構,擴展作為首要特性是必需的。 架構圖: 基礎: 主要 ...


概述

本文翻譯僅供學習之用,瞭解Orchard工作原理設計思想、技術點及關鍵詞,如有缺漏請不吝指正。鑒於能力有限定有諸多曲解或不完整的地方,請海涵。不定時完善整理。

CMS不像常規的web程式,它更像一個程式容器。 設計系統時採用一個開放類型的架構,擴展作為首要特性是必需的。


架構圖:


基礎:

主要使用以下現有的框架和類庫

  1. ASP.NET MVC: web開發框架。 MVC 關註分離
  2. NHibernate: ORM工具. 將Orchard 內容持久化 、通過移除模塊開發的持久化關註極大的簡化了數據模型
  3. Autofac: IoC container 依賴註入容器 . 大量使用DI (dependency injection 依賴註入 ) 。實現簡單,而且範圍生命周期都由Orchard Framework進行管理 .( IAuthorizationService, RolesBasedAuthorizationService and XmlRpcHandler.)
  4. Castle Dynamic Proxy: 動態代理.

Orchard Framework

Orchard Framework是建立在這些基礎上的一個額外的抽象層。也是最深的層。它包含了程式引擎 還有不能被孤立成模塊的部分,他們就是基礎模塊依賴的--也可以成為基礎類庫。

啟動Orchard

web application啟動後,Orchard Host被創建,在應用程式域級別是個單例。
the hos獲得使用ShellContextFactory的當前租戶(current tenant)的Shell。租戶:程式的實例,該程式按照用戶隔離,運行在同一應用程式域中, 提高了站點密度(其實是一個邏輯站點的意思。Orchard支持在一個物理的站點上建立多個邏輯的站點。每個邏輯站點都是獨立,有自己的數據,自己的主題等) 。
Shell是Tenant級別的單例,並且代表了該Tenant。他可以有效提供tenant-level的隔離同時對多租戶保持模塊 編程模型無關的。
shell一旦被創建就可以獲得ExtensionManager可用擴展列表。擴展包括模塊和主題.預設實現是掃描 模塊主題的擴展目錄。
同時從ShellSettingsManager獲得該用戶的設置列表。預設實現從App_Data子文件夾中獲取,但是也可以從其他地方獲得。
shell獲得CompositionStrategy對象,並用它為當前host的擴展列表和當前租戶的設置列表準備IoC容器。它返回的結果ShellBlueprint,不是shell的IoC容器,他是依賴、控制器、記錄藍圖的列表。
ShellSetting列表(每個租戶) 和ShellBluePrint 被扔到ShellContainerFactory.CreateContainer 獲得ILifetimeScope--主要使IoC容器界定範圍在租戶級別以便模塊依賴註入時也被指定到當前租戶不需要任何特別配置。

Dependency Injection 依賴註入

Orchard中,創建可註入的依賴關係的標準方法:創建一個介面繼承IDependency或其派生介面,然後實現該介面。在
消費方,在構造函數採用該介面類型的參數。framework將會發現所有依賴關係、負責實例化並按需註入實例。中
三種不同的依賴關係範圍,通過繼承相應的介面:
•Request: 每次HTTP請求都為創建依賴實例 請求一旦被處理就會將其銷毀。繼承IDependency。 reasonably cheap to create
•Object: 一個對象對介面產生依賴性就會每次創建一個新的實例。實例不會共用。 繼承ITransientDependency。 extremely cheap to create.
•Shell: 每個shell/tenant有且只有一個實例。 繼承ISingletonDependency. 需要維持shell生命周期的狀態 。

替換現有的依賴

通過OrchardSuppressDependency特性修飾類進行現有依賴的替換--使用完全限定的類型名稱作為參數進行替換。

依賴排序

一些依賴不是唯一的 而是列表的一部分。一些依賴不是唯一的 而是列表的一部分。通過修改模塊的清單中 feature 的Priority屬性。

Features:
    Orchard.Widgets.PageLayerHinting:
        Name: Page Layer Hinting
        Description: ...
        Dependencies: Orchard.Widgets
        Category: Widget
        Priority: -1

ASP.NET MVC

Orchard建立在ASP.NET MVC,但為了添加如主題、租戶隔離等功能,引入了一個額外的中間層 用於呈現mvc端 的期望內容 並且在Orchard端 按照Orchard內容級別上分割事情。
請求特定視圖時,LayoutAwareViewEngine開始啟動。 嚴格來說 ,這個不是一個新的視圖引擎,他不關註真正的呈現,它通過查找依賴於當前主題的正確視圖,並將 呈現工作委托真正的視圖引擎。
相似的, route providers, model binders and controller factories 作為 單一入口點而且將請求分派到恰當底層對象。
對於routes,我們有 多個 providers of routes(一般來自 modules 層)和 one route publisher .model binders controller factories 也是如此。

Content Type System 內容類型系統

Orchard中為了提供必要的靈活性,內容通過實際的類型系統進行管理,該系統在某種程度上比.NET基礎類型更加豐富、動態化:類型在運行時動態組成並反射內容管理的關註點.

Types, Parts, and Fields

任意內容類型,包含站點管理員通過code-free方式創建的動態內容.這些內容有 具體處理一個特定的問題分內容聚合而成。原因是很多關註點涉及很多類容類型。
例如:blog列表、產品、一段視頻都會有路由地址、註釋和標簽。因此這些在Orchard中會被按照單獨的內容部分進行處理。 註釋管理模塊按照這種方式可以適用於任意內容類型,包括不明所以然的東東。

Parts 包含properties 、 content fields。Content fields 可以同樣的方式復用。特定的欄位類型將會被 系統部分或者內容類型 代表性的使用。

parts fields 的區別:操作的規模 以及語義。
Fields比parts更顆粒度更細。
例如 field 類型描述手機號碼或者坐標,然而 part類型描述的是一個整體(註釋(動作 包含lifetime lifecyle) 標記).

最重要的區別在於語義: part = "is a" 關係 field ="has a" 關係。
例如, T恤是一個產品 它有SKU和價格 屬性。你不會說T恤是個產品 T恤是個價格
T恤是個SKU.
"Shirt" content type 由 Product part組成。Product part由 稱作price 的Money field 和稱作 SKU 的String field組成。

其他的區別 你只有有且一部分 的給定類型/內容類型,讓你認為這是 is-a 關係
因此 part 有很多給定類型的fields.換而言之, part中fields 相當於field's t類型的字典。content type就是part類型的列表(不包含名字)。
如果你想content type有多個實例選擇field類型。

Content類型剖析

content 類型 通過 content parts 類型構建. 代碼級別,Content parts通常和如下相關的:

  • Record(記錄), part數據的POCO持久化.
  • model class 繼承並實現ContentPart<T> T record type
  • repository(數據倉庫) 不需要有模塊實現 負責數據訪問的對象
  • handlers(處理器). 實現IContentHandler介面 是一組事件處理器 是事件像 OnCreated 或 OnSaved.
    基本上在content item的生命周期內使用鉤子執行大量的任務.也參與content items構造函數的構建。基於ContentHandler的 Filters collection可以讓handler添加對content type添加常見的行為。
    例如: StorageFilter 更加方便的聲明 content part的持久化如何處理,只需執行代碼
    Filters.Add(StorageFilter.For(myPartRepository)); Orchard系統將會myPartRepository數據持久化到資料庫中。
    ActivatingFilter負責 多個 parts 合成一個類型
    調用方法Filters.Add(new ActivatingFilter<BodyAspect>(BlogPostDriver.ContentType.Name));
    添加body content part到博客帖子

  • drivers(驅動器). 更友好更專業的 handlers處理程式。 繼承ContentPartDriver<T> T a content part type。
    另一方面,Handlers是沒有指定類型的content part type。 Drivers 可以看作特定part的controller。 他通過theme引擎呈現形狀。

內容管理

ContentManager對象可以訪問所有的內容。它有對應的方法查詢content store,用於內容版本化和管理髮布狀態

事務

每個HTTP請求都會自動創建事務.請求中所有的操作都是環境事務(ambient transaction)的一部分
如果請求的代碼終止了事務,所有的操作將會回滾。事務不能明確的終止,那麼所有操作將會提交沒有明確的結果。

Request生命周期

我們以請求一篇博客文章的示例:
一篇博客文章的請求進來後,程式首先查找各個模塊可用的路由 然後查找blog模塊匹配路由。路由為請求指定了博客文章的controller action ,從content manager查找文章。
action基於請求主對像 在content manager調用BuildDisplay獲得Page Object Model (POM)。這樣文章就從content manager取回了。
博客文章有自己的controller,但並不適合所有的content types.核心路由部分的通用ItemController 會處理動態content types。ItemController的Display action 和 blog post controller一樣:通過標頭從content manager獲取內容,然後根據結果構建POM.
依賴佈局視圖引擎 確定的正確的視圖根據當前主題和在視圖命名上 model's type連同Orchard conventions 。
視圖內,會生成更多的動態Shape例如區域定義。
通過主題引擎按照出現的順序遞歸生成最終呈現內容,通過尋找正確的模板或者Shape方法來呈現每個在POM的Shape。

Widgets

一種內容類型,包含Widget content part和widget stereotype(鉛版)。同樣由parts 和 fields組成,這樣使用其他內容類型的編輯呈現邏輯進行編輯。共用行為模塊(Building Blocks), 任何現存的content part都會被widget復用,這樣開銷幾乎為0.
通過widget層,添加widget到頁面。該層是widget的集合。它有名字和規則,決定哪些頁面將會展示,widgets列表、相關區域佈置、排序、設置。
規則 通過IronRuby表達式 附屬於每層。這些表達式可以使用IRuleProvider的任何實現
Orchard直接提供了兩個:url、authenticated

站點設置

站點是一個內容條目(content item),內容條目可以讓模塊擴展額外的parts。這也是模塊可以配置站點設置的原理。
站點設置租戶級別。

Event Bus 事件匯流排

Orchard系統和模塊通過創建依賴關係介面、註入實現暴露擴展點。
通過實現的介面或者實現同樣名字和方法的介面借入擴展點。 換句話說,Orchard不需要嚴格的強類型介面通信,使插件以擴展一個擴展點不依賴於程式集的定義。
當擴展點觸發註入實現,事件匯流排就會發佈一條消息。監聽事件匯流排的對象就會將消息分派給 繼承一個合適的介面的類方法。

Commands 命令

Orchard很多操作可以通過admin UI使用命令行進行。這些命令由實現 CommandName特性修飾的ICommandHandler介面的類方法暴露出來。
命令行工具在運行時通過模擬網站環境和使用反射檢查組件發現可用的命令。該命令運行環境是儘可能接近實際運行的站點。

搜索和索引

搜索和索引的使用Lucene預設情況下實現的, 預設的實現可以被其他引擎所取代。

緩存

Orchard緩存依賴於ASP.NET緩存,但我們通過ICache介面暴露一個輔助的API,使用Get方法調用。如果緩存已經不包含所請求的實體,Get使用key和方法產生緩存實體值。
Orchard緩存API的主要優點是,它每個租戶透明地工作。

文件系統

文件系統根據環境被抽象以便直接存儲在物理文件系統上或者像Azure的雲存儲上。體模塊是使用該抽象文件系統模塊的一個例子。

用戶和角色

用戶是內容項(雖然不可路由),例如對於概要文件模塊易於使用其他欄位擴展。角色是content part 被焊接到users。

Permissions 許可權

每個模塊都可以公開一組許可權,以及如何將這些許可權預設情況下應授予預設角色。

任務

模塊可以通過調用的實現IScheduledTaskManager介面的CreateTask的類安排任務。通過實現IScheduledTaskHandler執行任務。Process方法檢查任務類型名稱並決定是否處理它。
任務自ASP.NET線程池的一個單獨的線程中運行。

Notifications 通知

模塊可以通過繼承INotifier並調用其方法之一 將管理界面展示消息。 獲取上INotifier的依賴,並調用其方法之一面消息到管理界面。多個通知可以作為任何請求的一部分進行創建。

Localization 本地化

應用程式及其模塊的本地化通過將字元資源包裝後傳入T方法:@T(“此字元串可以本地化”)。 Using the localization helpers
資源管理器從位於程式中的特定位置的PO文件載入本地資源字元串。

內容項目本地化通過不同的機制來實現:內容項目的本地化版本是物理上是由一個特殊的部分鏈接在一起的各個內容項。
culture管理器決定當前使用culture。預設實現返回已在站點設置中配置的culture,還可以從用戶配置文件或從瀏覽器的設置得到它。

Logging 日誌

通過繼承ILogger的實現日誌。不同的實現可將日誌條目發送到不同的存儲類型。 使用 Castle.Core.Logging進行記錄的實現。

Orchard Core

Orchard.Core程式集包含了一組運行必需的模塊。其他模塊可以安全引用這些模塊。
core modules:feeds, navigation 、routable.

Modules 模塊

系統內置模塊如 blogging or pages, 但第三方模塊也容易創建。
模塊僅僅是使用了擴展的manifest.txt文件ASP.NET MVC area。
一個模塊通常包含事件處理程式,內容類型,其預設呈現模板以及一些管理界面。
每當csproj文件或csproj文件引用的文件有變化時, 模塊可以動態​​編譯。不需要開發人員甚至使用IDE進行編譯。
模塊必須放置在Modules文件夾(Orchard.Web/Modules/MyModule)和文件夾名稱必須由項目產生的編譯的DLL的名稱相匹配。所以,如果你有一個名為My.Custom.Module.csproj自定義模塊項目,並將其編譯為My.Custom.Module.dll,模塊根文件夾必須命名為My.Custom.Module。 [~/Modules/My.Custom.Module/]

Themes 主題

基本的設計原則,即所有它生成的HTML可以從主題更換,包括模塊產生的標記。Conventions 約定確定文件對應主題的文件層級。
整個渲染機制是基於shapes。該主題引擎的工作是找到當前主題,因為主題確定呈現每個shape的最好方法。每個形狀可以具有可由模塊(views文件夾模板或在代碼shape方法) 定義一個預設的呈現。
該預設渲染可以由當前主題重寫。通過shape的模板版本或shape方法實現。
主題可以有父級,可以讓子主題定製化 或在父級上進行修改。系統提供了名叫Theme Machine的基礎主題作為父主題十分容易使用。
和模塊一樣,主題可以包含很多代碼: 有自己的csproj文件,並從動態編譯受益。主題定義方法,將設置暴露管理用戶界面。
通過繼承IThemeSelector 實現當前主題選擇,它們返回一個主題名稱和任何請求的優先順序進行。這讓很多選擇器作出貢獻的主題的選擇。系統提供了IThemeSelector四種實現方式:

  • SiteThemeSelector 選擇當前配置的租戶或網站具有低優先順序的主題。
  • AdminThemeSelector 只要當前URL是一個admin URL,接管並有返回高優先順序返回admin theme。
  • PreviewThemeSelector 如果當前用戶是發起主題預覽,使用預覽主題重寫站點當前主題
  • SafeModeThemeSelector 應用程式是在“安全模式”該選擇器才可使用是唯一的選擇時可用的,通常在安裝過程中發生。它具有非常低的優先順序。

主題選擇器的一個例子可能是一個促進當UA被識別為屬於一個移動設備的移動的主題。


引用

參考:http://www.cnblogs.com/esshs/archive/2011/06/01/2067501.html
POCO參考:http://kb.cnblogs.com/page/89750/
環境事物 參考:http://www.cnblogs.com/artech/archive/2010/01/30/1660088.html
POM 參考:http://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html


2016.4.17 v0.1


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 入住博客園4年多了,一直都是看別人的博客,學習別人的知識,為各個默默無私貢獻自己技術總結的朋友們頂一個;這幾天突然覺得是時候加入該隊列中,貢獻出自己微弱的力量,努力做到每個月有不同學習總結,知識學習的分享文章。以下要分享的是花了兩天時間編寫+測試的windows下C#定時管理器框架-Task.Mai ...
  • ...
  • TabControl控制項的TabItem的Content元素,例如:DataGrid控制項,在對事件的處理時,需要對事件的源引起關註,當需要處理DataGrid的事件時,事件會傳遞到TabControl中,解決這種問題的方法如下: 方法一:判斷觸發此事件的源是誰,根據事件的源再做相應處理 方法二:註冊 ...
  • wpf
    1.WPF 設置TextBox為空時,背景為文字提示。 <TextBox FontSize="17" Height="26" Margin="230,150,189,0" Name="txt_Account" VerticalAlignment="Top" Foreground="Indigo" T ...
  • 彈幕功能通常用於實時顯示當前視頻或者文檔的評論內容,在上快速飛過的方式呈現,看起來比較酷炫。 這種典型的多用戶實時交互的功能,很適合使用SignalR實現,通過SignalR提供後臺的服務推送功能,客戶端接收消息後呈現出來。 彈幕功能實現起來有點類似聊天室的功能,只是消息的展示方式不同,所以結合Si ...
  • 什麼是LocalDB 隨著SQL Server 2012的發佈,LocalDB躍入我們的視線,它可以被看做是SQL Server Express的輕量級版本。LocalDB專門為開發人員創建,它非常易於安裝,幾乎無需管理,相容T-SQL語言,編程介面與SQL Server Express別無二致。有 ...
  • [源碼下載] 背水一戰 Windows 10 (7) - 控制項 UI: VisualState, VisualStateManager, 控制項的預設 UI 作者:webabcd介紹背水一戰 Windows 10 之 控制項 UI VisualState 和 VisualStateManager 控制項的 ...
  • 記得最開始 using System.Text.RegularExpressions; Regex m_regex = new System.Text.RegularExpressions.Regex("^(-?[0-9]*[.]*[0-9]{0,3})$"); bool b = m_regex.I ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...