1. 首次深入Orchard应了解的基本知识: 用户的角色
查看的文章来自: http://www.orchardch.com/Blog/20120503063810
用户: normal user(reader/visitor/guest)
管理员: administrator 所有管理权限
设计人员: designer 可以修改网站的外观
主题文件 布局layout和区域zone
视图.cshtml
样式表: js/media/css
部件 widgets
区域中还有层,层中可以指定放哪些内容或部件
开发人员: developer 理解Orchard架构并能扩展它
主题Theme:
布局Layout
区域Zone: 层和内容,内容可以是部件
模块Module
扩展模块: 指大的功能性模块
主题模块: 指外观呈现模块
内容模块: 某个内容类型所需要的东西
部件模块: Widget 内容模块里一些小的可视内容
内容Content: 网站前端显示的数据
内容类型与内容项:
内容类型就是类,内容项则是内容类型的一个实例
内容元件: 可以内容类型中共享的元件
一个内容类型中只能存在同一个内容元件
内容字段: 更小的内容类型
记录Record: 保存内容类型/元件/字段至到数据库的记录
总结:
页面: 主题Theme(主题模块) --> 布局Layout --> 区域Zone --> 层 --> 内容
内容:
内容类型(内容模块) --> 内容元件/内容字段 --> 记录Record --> DB
内容项
部件模块Widget
2. Orchard是如何运行的: Orchard机制
http://www.orchardch.com/Blog/20120503090054
CMS: 必须建立一流的可扩展性功能,必需是一个非常开放式的构架
2.1. Orchard构架(直接运行Orchard.Web)
最顶上是Theme主题(也是扩展模块)
A. Modules
主要是Modules文件夹下的内容(是否是指扩展模块 ????? )
B. Core
主要是Core文件夹下的内容,以及Orchard.Core.dll
是否是指Orchard的核心模块——必须模块(如:主题模块/内容模块/部件模块等) ?????
C. Orchard Framework
主要是 Orchard.Framework.dll(命名空间不含Framework)
Orchard Framework是Orchard的最底层,它包含了应用程序引擎和至少不能被分离成模块的部分。
这些都是必须的东西,甚至最基本的模块也不得不依赖它,可以将它理解为Orchard最底层的类库。
D. ASP.NET MVC/NHibernate/Autofac/Castle
MVC关注分离
Nhibernate关注ORM
Autofac关注IoC依赖注入
Castle动态产生代理
Orchard程序和框架在这些框架的基础上构建额外的抽象层( Orchard.Framwork ????? ),
根据Orchard的开发指南,对于Nhibernate,Castle,Autofac,
有许多方式实现细节我们并不需要了解。
E. .NET ASP.NET
F. IIS or Windows Azure
Orchard.Web中会动态编译以下三个文件夹,这三个文件夹中含有源码
Themes/
Modules/
Core/
2.2. Orchard启动
Orchard启动
--> Host:
Host是应用程序域创建的应用程序域层的单例
--> Host取得Shell:
Host使用ShellContextFactory取得当前租户Tenant的Shell
某个Shell实例代表某个租户Tenant实例
租户是按识别用户被隔离的应用程序实例
他们运行在同一个应用程序域中,这增加了网站密集度
Shell是租户层的单例,事实上代表着租户,
它有效提供了租户层隔离对象同时对多租户模块编程模型无关
--> Shell初始化: 获取Extension:
Shell一旦建立,将从ExtensionManager获取可用的扩展
扩展是模块和主题,默认实现了扫描modules和themes目录的扩展
--> Shell初始化: 获取租户的设置列表
同时,shell从ShellSettingsManager获取租户的设置列表
默认会从appdata适当子目录获取设置列表,但能从不同地方获取设置
--> Shell初始化: 获取CompositionStrategy(合成策略)对象
--> Shell初始化: 从可用扩展中为当前host准备IoC container(IoC容器)
2.3. Orchard中的依赖注入
Orchard中创建可注入依赖的标准方法是直接或间接实现IDependency 接口。
在构造器中能得得接口类型的参数。
application framework会发现所有依赖并在需要时初始化和注入实例。
2.3.1. Orchard依赖注入的范围
(1) Request
为每个http请求创建的依赖实例,并在请求完成后销毁。
(2) Object
创建新的实例,在接口上对象每一次依赖。实例不共享,
派生自ITransientDependency,对象必须很容易创建。
(3) Shell
每个shell/tenant仅创建一个实例,派生自ISingletonDependency,
为shell的生命周期必须维护一个公共策略
2.3.2. 替换现有的依赖
可以用OrchardSuppressDependency 特性来标记您的类,替换现有的依赖,
需要完全合格的类型作为参数去替换
2.3.3. 排列依赖性
一些依赖不是唯一的,而是有部分列表。
例如:处理程序都在同时激活,有些情况你要修改这些依赖创建的顺序,
这个可以通过修改模块的manifest实现,使用feature的 Priority属性。
2.3. Asp.NET MVC的间接层
2.3.1. 为什么需要引入间接层?
Orchard基于ASP.NET MVC构建,为了添加像主题和租户隔离这样的东西,
需要引入一个额外的间接层,展示ASP.NET MVC上提出的概念,将在Orchard概念层中分离。
例如:当请求一个指定的view时,LayoutAwareViewEngine引入 ,
严格地说,它不是一个新的视图引擎,它包含了依赖当前主题去寻找正确view的逻辑,
代理了实际视图引擎的渲染工作。
2.3.2. 其它间接层
也提供了route providers, model binders and controller factories,
作为ASP.NET MVC的单一入口点和在适当范围内对象下分发请求。
在路由情况下,我们能提供很多路由,并且一个路由发布到ASP.NET mvc,
model binders and controller factories也是同样的
2.4. 内容类型系统
Orchard中的内容是在类型系统下管理的。
在某些方面是比.net类型系统更丰富和更灵活的一个的类型系统,
能给web CMS提供必要的灵活性,类型必须在运行时动态组合以反映内容管理的灵活性。
2.4.1. 类型,元件和字段
Orchard能处理任意内容类型,包括一些管理员以代码的方式动态创建的。
这些内容类型是内容元件的聚合,因为元件关系到许多的内容类型。
例如:博客,产品,视频可能都有路由地址、评论、标签,
所以Orchard中路由地址、评论、标签分隔成内容元件,
这样路由地址、评论、标签模块就只需要开发一次并就用到这些内容类型中。
元件可以拥有自己的属性和内容字段,字段同样也是可复用用的,
元件和字段的区别是他们的范围和语义不同。
字段比元件的粒度更小,例如:字段可能描述一个phone number 或 email address,
但是元件可能就是描述了评论或标签的整个范围。
主要的区别还是语义上的:
元件是实现了”is a”关系,
字段实现了”has a”关系。
例如:一件衬衫is a 产品,has a 名称和价格。
2.4.2. 内容类型剖析
内容类型是由内容元件构建的,内容元件代码通常与下面的有关联:
(1) Record
是part数据的POCO表示
(2) Model
实体的part,从ContentPart<T>继承,T是record type
(3) Repository
模块作者不需要实现Repository,Orchard将能使用一个通用的。
(4) handlers
handlers实现了IContentHandler接口,是事件处理的集合,如OnCreated , OnSaved。
基本上他们在内容项目的生命周期中执行多项任务。他们也能参与构造器内容项目的实际组成。
有一个基于ContentHandler 的Filters集合,为内容类型添加公共行为的处理程序。
例如:Orchard提供了一个StorageFilter,
使它很容易的声明 如何持久化内容类型 应该怎么处理:just do drivers.
(5) driver
是更友好更特别的处理程序(因此不太灵活)
它与一个指定的content part type关联(从ContentItemDriver 继承,T 是一个content part type)。
另一方面的处理器没有指定一个content part type.Drivers 能看做具体part的 controller,
他们通常建立主题引擎呈现的shapes。
2.4.3. 内容管理
所有的内容都通过ContentManager对象访问,这让你使用事先不知道类型的内容成为可能。
ContentManager 一些方法,查询内容存储库,内容版本,并管理发布状态。
2.4.4. 处理(Transactions)
Orchard自动为每个HTTP请求创建一个事务,这意味着请求过程中的所有操作都是事务中的一部分。
如果请求代码中断,所有数据操作都将回滚。
如果事务没有显示取消,请求结束所有操作都会提交,不需要显示commit。
2.4.5. 请求的生命周期(Request Lifecycle)
下面介绍一篇博文的请求。
当请求一篇指定的博文,程序首先寻找各种模块定义的可用的路由并找到博文模块匹配的路由,
然后路由解析请求发给blog post控制器的action item,action将从content manager查询博文,
这个action从基于请求的主要对象的content manager(叫BuildDisplay)获取 Page Object Model,
从content manager检索这个博文。
博文有自己的controller,但不是所有content type都有。
例如:动态内容类型被Core Routable part的许多通用ItemController服务,
ItemController的显示行为几乎与博文的controller做同样的事,
它从 content manager取得content item 然后从结果创建POM。
布局视图依赖当前的主题和使用的模块类型一起解析正确的视图,视图内,许多动态的shape被创建。
比如zone,找到正确的template或shape method 呈现每个shape ,
主题引擎实际呈现在POM中遇到的shape出现的顺序和递归。
2.4.6. 部件(Widgets)
部件是有Widget content part和widget stereotype的内容类型。
像任何其他的内容类型,由元件和字段组合而成。
这意味着,他们可以使用同一版本的编辑和渲染其他类型的内容的逻辑,
他们像积木一样任何content part能像widget的一部分被重用。
部件能过部件层级添加到页面,层级是部件的集合,他们有名称,规则,
确定能出现在网站的哪个页面、部件列表、关联区域位置、排序、设置。
每个层级的规则使用IronRuby表达式,在程序中所有IRuleProvider的实现都能使用这些表达式,
Orchard有两个box实现:url 和 authenticated.
2.5. 其它
2.5.1. 网站设置(Site Settings)
Orchard中的网址是一个内容项,这使得它可以为模块添加额外的元件,
这是模块能如何进行site settings,每个租户都有Site settings。
2.5.2. 事件总线(Event Bus)
Orchard和它的模块通过创建依赖接口暴露扩展点,然后实现注入。
通过实现它的接口完成插入扩展点,或实现与接口具有相同的名称和方法。
换句话说,Orchard不需要严格的强类型接口通信,启用插件扩展扩展点不需在程序集上定义的地方依赖。
这仅仅是Orchard 事件总线的一种实现,当扩展点用调用注入实现,
一条消息被发布在事件总线上,以适当命名的接口派生的类中的方法的对象之一监听事件总线发送的消息。
2.5.3. 命令(Commands)
Orchard网站的很多行为都能通过命令行执行。
这些命令是实现了ICommandHandler的类中的标记了CommandName 特性的方法。
Orchard命令行工具在运行时模拟网站环境和使用反射检查程序集来发现可用的命令。
命令执行的环境尽可能的实际运行的网站。
2.5.4. 搜索和索引(Search and Indexing)
搜索和索引默认通过使用Lucene来实现,但是默认实现可以用其它索引引擎替换。
2.5.5. 缓存(Caching)
Orchard中的cache依赖 ASP.NET cache,但是我们暴露了一个helper api,
可以通过一个ICache类型的依赖调用get方法使用。
如果cache没有包含请求项,Get方法取得key和function可用于生成 cache entry’s value。
使用Orchard cache api的主要好处是每个租户透明地工作。
2.5.6. 文件系统(File Systems)
Orchard中的文件系统是抽象的,以便存储能被定向到物理文件系统或Azure的blog存储的备用存储,取决于环境。
Media模块就是使用抽象文件系统的例子。
2.5.7. 用户和角色(Users and Roles)
Orchard中的用户是content items,一个很容易为一个模块的配置并用额外的field扩展它们的content item,
角色是能被链接到用户的content part。
2.5.8. 权限(Permissions)
每个模块都能公开一组权限,以及如何将这些权限授予Orchard的默认角色。
2.5.9. 任务(Tasks)
模块能通过调用IScheduledTaskManager类型的依赖的CreateTask方法安排任务。
该任务能被实现了 IScheduledTaskHandler接口的类型执行。
这个执行方法能检查任务类型名称并决定是否处理。任务在ASP.NET线程池的一个单独线程上运行。
2.5.10. 通知(Notifications)
模块能使用INotifier 依赖并调用它的方法在管理界面浮出消息,
任何请求的一部分可以创建多个通知。
2.5.11. 本土化(Localization)
程序和模块的本地化通过调用T()方法中包装字符串资源来完成,
@T("This string can be localized")Orchard的资源管理能从位于程序指定位置的PO文件装载本地化的资源字符串。
Content item的本地化通过不同的机制完成:content item的本地化版本是物理上独立的内容。
目前使用的文化是由culture manager决定。
返回文化的默认实现在site setting中设置,但一个备用实现可以从用户配置信息和浏览器的设置获取。
2.5.12. 日志(Logging)
日志依赖ILogger实现,不同的实现可以发送到不同存储类型的日志条目。
2.5.13. Orchard Core
Orchard Core程序集包含一组Orhcard运行所必须的模块。
其它模块可以安全地依赖到这些模块上,这些模块总是可用的。
比如 feeds,navigation,routable模块。
2.6. 模块(Modules)
Orchard默认发行版包含了一些内置模块,像 blogging,pages,但第三方模块也同样能创建。
一个模块就是扩展Orchard的包含manifest.txt文件的ASP.NET MVC Area。
一个模块通常包含事件处理程序,内容类型,它们的默认呈现模板以及一些管理界面。
每次修改模块都能从源代码动态编译。这种”记事本”风格的开发并没有指定需要显示编译或甚至需要使用Visual Studio。
2.7. 主题(Themes)
这是Orchard中的基本设计原则,产生的所有HTML都能用主题替换,其中包含模块产生的标记。公定了文件必须在主题中的层次。
Orchard中的渲染机制基于shapes,主题引擎的工作是查找当前主题以及确定渲染每个shape最好的方式是什么。
每个shape能有一个默认的渲染,可以由模块在代码中定义。
像视图目录中的模板或像一个shape方法,默认渲染可能被当前的渲染覆盖。
主题可以有一个父主题,能使子主题专门化或改写。
Orchard自带了基础默认主题叫 Theme Machine,设计成作为父主题很容易使用。
主题能包含代码,他们能有自己的csproj文件,有利于动态编译。
这使主题定义shape方法,但也会暴露其拥有的所有设置管理界面。
当前主题的选择通过实现IThemeSelector的类实现,
返回主题名称和任何请求的优先级,Orchard自带了IThemeSelector的4个实现。
SiteThemeSelector 为当前租户的配置或低优先级的网站选择一个主题。
AdminThemeSelector 返加一个高优先级的admin主题,只要当前URL是一个管理url。
PreviewThemeSelector 预览主题。
SafeModeThemeSelector 当应用程序运行在 safe mode时 是唯一的可选项,通常在安装时使用,它有一个非常低的优先级。
主题选择的一个例子:可以使用户使用移动设备时推出一个移动主题。
---------------------
作者:liuweitoo
来源:CSDN
原文:https://blog.csdn.net/liuweitoo/article/details/8156446
版权声明:本文为博主原创文章,转载请附上博文链接!