Orchard

Orchard工作原理

概述

本文翻译仅供学习之用,了解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

时间: 2024-10-05 12:37:53

Orchard的相关文章

Orchard 之:Widget,兼看 Layer 在权限控制中的作用

一:Widget 可以理解为控件,可以直接被页面所引用.行为类似与分部页面,比如,我们可以创建一个 商品列表 Widget,然后这个 Widget 就可以被很多页面所引用. 理解 Widget 这个概念,我们不得不理解另外两个概念: 1:Layer Orchard 默认有这么几个层,Default.Authenticated.Anonymous.Disabled.TheHomepage.Layer 用于承载什么时候 Widget 将会被展现,这么讲大家一定觉得很抽象,其实 Layer 存在的意义

2 Orchard汉化资源包的使用

Orchard安装完毕之后我们就可以在后台尝试做一些基本的操作感受下Orchard提供的一些功能,比如添加一个页面.菜单.文章什么的.也可以试着新建一些部件.布局之类的感受下.个人建议摆弄一下了解下就可以,因为我们现在对Orhard的系统设计还没有一个很好的认识,所以很多东西都会感到摸不到头脑,因此也没必要在这里花费太多精力. 对于本人这种英语渣来说,还是搞不定这全是英文的站点,Orchard项目在设计之初就已经考虑到了全球化的问题.官网上面也提供了本地化包.只要下载对应的本地化包就可以将网站设

Orchard分类Taxonomies图文教程

Orchard分类和标签都实现对内容的分类管理,两者区别是分类的子项之间是具有级别(同级.上下级)关系,而标签是很随意的,子项之间可以有关系也可以没有,今天给大家分享分类的使用方法. 一.环境说明 Orchard版本1.9.2,主题默认TheThemeMachine 二.建立分类 打开Orchard,切换到Dashboard,在左侧菜单栏找到Taxonomies并单击,在页面右击找到“Add a Taxonomiy”并单击,由于分类本身也是个类型,所以不支持中文,我们先建一个Subject,保存

Orchard官方文档翻译(十一) 使用Tags组织文本

原文地址:http://docs.orchardproject.net/Documentation/Organizing-content-with-tags 想要查看文档目录请用力点击这里 最近想要学习了解orchard,但却没有找到相关的中文文档,只有英文文档.于是决定自行翻译,以便日后方便翻阅. 转载请注明原作者与出处. 本人英文水平有限,错误之处欢迎指出以便修正 使用Tags组织文本 Content Orchard中的文本内容可以通过tags标签来分类.我肯可以通过URL中附加的关键字来进

Orchard官方文档翻译(六) 建立你的第一个Orchartd站点

让我们开始 该主题内容已在Orchard1.8Release版本下测试通过. 这里通过向导式的教程来告诉大家Orchard的功能如何使用.如果你是第一次使用Orchard,该文档就是为你而准备的! Orchard使用从零开始 对于初次接触Orchard的你来说,这里就是你的圣地,因为你能在这里找到最新的Orchard资源. Orchard 初学者 Orchard CodePlex - Orchard代码库 Orchard 讨论区 - 关于Orchard讨论区 Orchard 文档 - 与Orch

把Orchard部署到Windows Azure Web Sites

很久前就想做个人站点,主要用来记录自己的生活,我喜欢摄影,烘焙…然后又刚刚入皮坑,这些都可以放在网站上展示一下,或许还能为自己带来收入. 然后手上刚好有Azure的试用,于是乎动力就上来了. 以下是部署步骤. 一.创建Web Sites,SQL Database ,并下载Orchard源码 这些步骤超级简单就不再手把手教了,据说7月份Web Site的收费标准才会出来.到时候看看自己能否供得起 = = 昨天看到1.8.1 RC出来了….版本更新真快. 源码下载地址如下: https://orch

Orchard运用 - 理解App_Data目录结构

了解一个系统,应该基本上要了解目录结构及其组织形式.这样对于开发人员更是必备的知识,比如开发模块最终安装到哪,主题Themes是如何配置启用. 今天跟大家分享其实是个笔记记录,就是看到有一篇文章介绍App_Data目录结构,标注一下其他心得: Orchard网站App_Data目录里的文件介绍 其实目前对我来说: Logs目录:这是存放系统日志的目录.查看日志文件可以检查系统在运行中都出现了哪些错误.默认文件名按照日期标记. 在此你可以看到所有的错误信息,比如模块出错了,添加Alternativ

Orchard运用 - 在页面每篇随笔添加编辑链接

今天继续捣鼓Orchard系统,在此分享一个小技巧,如何在页面每个随笔添加编辑链接,这样方便管理员直接点击进去编辑内容.是的,只对管理员可见. 话说这一个特性一开始是默认启用并集成在核心实现中的,后来分离并封装到一个新的模块,该模块名称叫"Content Control Wrapper", 不过需要你启用它 - 很简单, 管理页面进入模块页面,搜索"Content"并找到该模块,点击Enable激活即可. 参考链接 http://stackoverflow.com/

ORCHARD 是什么?

Orchard 是由微软公司创建,基于 ASP.NET MVC 技术的免费开源内容管理系统: 可用于建设博客.新闻门户.企业门户.行业网站门户等各种网站 简单易用的后台界面 性能稳定,功能齐全 热拔插模块化架构提供超强可扩展性 BSD 协议授权,可用于商业闭源项目 http://dotnetnuke.codeplex.com/SourceControl/latest http://www.orchardch.com/ 是一个以微软为主导的开源CMS项目,它允许使用者在.Net平台上快速建立网站,

想当站长请立即使用Orchard

其实早在很多年前我就一直有一个梦想,那就是那个网站当个站长,和各位有共同爱好的人成为朋友,很多年了虽然有了这个能力却没有了这个心情,成为了程序员却天天被程序玩. 最近几年一直从事C#方面的软件开发,基本上C#方面开发技术都有用过,MVC.WPF.Asp.Net.Xamarin等.从我多年的开发经验来看,还 是前端相对来说比较辛苦点,客户的问题永远解决不完,首当其冲的就是前端开发者,虽然我尽量的想转后端,奈何后端早已被JAVA承包.    最近心血来潮又想玩玩网站了,自己抽空也写了个简单的博客软件