文章翻译自http://docs.orchardproject.net/Documentation/How-Orchard-works
对Orchard的理解还不深刻,翻译可能有不好的地方.
开发CMS不同于开发其它的web项目,CMS的首要目标就是要支持扩展.
Orchard 架构
Modules
Core
Orchard Framework
ASP.NET MVC NHibernate Autofac Castle
.NET ASP.NET
IIS or Windows Azure
Orchard的地基
Asp.net MVC
NHibernate
Autofac
Castle Dynamic Proxy
Orchard Framework
Orchard Framework是最复杂的部分, 包含了Orchard的引擎和一些不能划分到模块的部分. 几乎所有的Module都依赖于它, 你可以将它看成是Orchard类库。
启动Orchard
当Orchard启动的时候,会创建一个Host, host是App domain 级别的单例
下一步, host通过ShellContextFactory取得当前tanant的Shell.
tannat是一个程序实例, 不同的tannat有不同的用户,他们分属于不同的tannant而不知道其它tannat的存在。这个的目的是为了增加网站的密度。
shell是tanant级别的单例, 是tanant的具体呈现, 也是具体实现tannant隔离性的.
shell一旦创建, 将从ExtensionManager中获取所有可用扩展, 这些扩展包括Module和Theme. 默认的实现是会自动扫描Module和Theme文件夹.
同时shell会从ShellSettingsManager获取tannat的setting, 默认的实现会从Appdata的子文件夹中获取。但是可以修改实现从其它地方获取, 比如你有Azure 的实现, 使用blob storage而不是Appdata, 因为Appdata在那个环境下不可写
shell然后取CompositionStrategy对象, 使用它构建IoC容器, 包含当前host的扩展和当前tanant的setting. 结果不是shell的IoC容器, 而是ShellBlueprint, 一个包含依赖项, controller和record的蓝图.
依赖注入
典型的在Orchard中使用依赖注入的方法是创建一个接口继承IDependency或者它的子接口,然后创建类实现这个接口。
在使用依赖注入的地方, 你可以把这个接口类型作为构造函数参数, 这样程序就能够自动的发现依赖, 创建实例注入
有3中不同的生命周期, 所以要选择好从哪个接口继承:
Request生命周期: 每个Request请求的时候,创建一个,这样的依赖必须创建的开销要小。从IDependency接口继承.
Object生命周期: 这要使用到了,就创建新instance, 这个依赖的必须创建的开销更小. 从ITransientDependency接口继承
Shell 生命周期: 一个shell/tanant才一个实例, 从ISingletonDependency继承。注意只能要来保存一些shell/tanant级别的类型
替换已有的依赖
可以通过使用OrchardSuppressDependency  attribute包装你的类来达到替换现有依赖的目的。
依赖排序
有些依赖不是一个对象,有可能是一个List.
有时候,你想修改它们的顺序, 这个可以通过修改module的manifest实现, 使用Priority属性, 如下例:
Features:
Orchard.Widgets.PageLayerHinting:
Name: Page Layer Hinting
Description: ...
Dependencies: Orchard.Widgets
Category: Widget
Priority: -1
Asp.net MVC
Orchard是asp.net mvc实现的,但是为了实现Theme和tanant, 我们添加了一层.
比如, 当需要呈现某个view的时候,LayoutAwareViewEngine会先介入. 严格的说,这不是一个新的View Engine, 它不关注如何具体呈现,而是关注如何根据当前的Theme帮助寻找正确的view, 然后通知View Engine渲染.
这个类似于route providers, model binders和controller factories, 他们都是实现根据具体请求来实现分发的功能。
Content type系统
Orchard中的Content是由真实的类型系统管理, 比.net中的类型系统更加丰富和动态。为了在CMS中提供灵活性,Orchard中的content type必须在运行时组合。
Types, Parts和Fields
Orchard能够处理任意的content type, 即使是由网站管理员在coe-free manner中动态创建的. 这些Content type都是为了应付某个特定需求的.
比如, 一篇blog,产品和视频都有address, comment和tag. 所以, address, comment和tags在Orchard中被区分为不同的content type. 这样,comment管理模块就只需开发一次然后应用到任意的conent type.
Fields比parts的粒度更小. 比如, Field可能只是用于描述一个电话号码, 而part会用来描述comment, tag这样一个完整的部分.重要的区别是, part表示的是"is a"的概念,而field表示的是"has a"的概念
比如, 衣服是产品, 它有SKU和price, 所以衣服这个Content type是由产品part组成, 而产品part是由Money类型的price和sting类型的SKU组成.
另外一个说法是part是一堆fields的字典,每个field有对应的name. content type是有一堆part type组成的。
这里给出了如何判断选择part还是field, 如果你的content type是会有多个实例, 那么就应该选择field
剖析Content Type
Content type是由Content parts组成的. Content Parts一般有下面组成:
  • a record, 以POCO的方式来呈现part的数据
  • 一个model类继承自ContentPart<T>, 这里的T就是Record的数据类型
  • a repository. 这个repository不是必须有module来提供, 因为Orchard会默认会使用通用的
  • handlers. handlers继承自IContentHandler, 包含一系列的event handlers, 比如OnCreated和OnSaved. 它们是content生命周期的hook, 达到在content生命周期中完成一些任务的目的。它们也可以通过content的构造函数来参与构建content. 在Base ContentHandler中, 有一个Filters的集合, 通过这个集合handlers可以为content type添加一些行为. 比如, Orchard提供了StorageFilter, 使得一个content type非常容易的声明如何实现持久化, 只需要Filters.Add(StorageFilter.For(myPartRepository))
  • drivers. Drivers是更加友好和特殊的handler. handlers不和特定的content type关联, 而drivers可以看做是特定part的一组Controllers. 它们常用于构建shapes, 然后由theme engine渲染.
Content Manager
Orchard中的所有cnotent都是通过ContentManager对象访问的, 这也使得我们能够在不知道content的类型的时候,就能够使用它.
ContentManager提供了方法访问content store, 版本管理contents, 和管理content状态
Transactions
Orchard会自动地为每个http request创建transaction. 这也意味着一个request过程中所有的操作都是在transaction管理下的. 如果request abort transaction, 那么所有的数据操作都会回滚. 如果transaction没有被取消,那么在request结束的时候,所有的数据操作会自动提交。
Request生命周期
这里,我们拿request获取一篇博客作为例子.
当接收到一个请求要获取一个blog post, 程序首先在所有可用的routes中选择匹配的route, 这些route是有各个modules提供的. 当找到匹配的blog module的route, route会解析到特定的action, action会从content manager中获取post, 然后action从content manager中获取一个Page对象(通过BuildDisplay方法)
blog post有它自己的controller, 但是并不是所有的content type都是这样. 比如, 动态的content type是有Core Routable part中对的通用的ItemController来处理的.
Layout view enginge将会根据当前的theme和model的类型来使用正确的view. 通过view, 动态shape创建.
Widgets
Widgets是content type, 包含widget content part和widget stereotype. 和其它的content types一样, 它也是由parts和fields组成的. 这意味着它们和其它的content type一样编辑和渲染, 也意味着content part也能够比widget使用.
widgets通过widget layers添加到pages中. Layers是widgets的组成. 它们有name, 有rule决定网站中的那些pages能够显示, 和一组widgets,相关的zone placement和ordering, settings.
layers的rules是以IronRuby expressions的形式表示. 这些expressions能够使用任何从IRuleProvider继承的类.
Site Settings
orchard中的site是一个content item, 这就使得modules可以为它拼接其它的parts. 这也是为什么modules能够改变site settings.
Site settings对于每个tenant是独立的.
Event Bus
Orchard和它的modules通过interfaces来暴露扩展点, 实现这些interface可以达到注入的目的.
为扩展点扩展可以通过继承这些interfaces, 或者通过实现一个接口,名字一样,方法也一样. 也就是说, orchard对类型没有强制要求.
Commands
Orchard中的很多action可以通过admin UI和命令行执行. 这些命令通过类继承ICommandHandler, decorated with CommandName attribute.
Orhcard command line tool在运行时发现可用的命令, 模拟web site的环境.
Search and Indexing
search和indexing是通过默认使用Lucene, 你也一个通过替换成其它的indexing engine.
Caching
Orchard中的cache是基于asp.net的cache, 通过接口ICache的Get方法. Get提供一个key和一个function用来生成对象,如果没有对应key的对象,就用function创建一个.
使用Orchard API的优势是cache对于每个tenant是独立的.
File Systems
Orchard中的File system是抽象的, 所以存储可以放到物理存储中, 或者其它的替代, 比如Azure blob storage.
Media module是使用抽象file sytem的一个例子.
Users and Roles
在Orchard中, Users是content items, 所以可以非常方便的扩展其它的fields. Roles是content part 用来拼接到Users.
Permissions
每个module能够暴露一组permissions, 这些permissions对于orchard的默认roles如何设置
Tasks
模块能够创建tasks通过调用IScheduledTaskManager中的CreateTask方法. Task能够被实现IScheduledTaskHandler的执行. 执行处理的方法会检查task的类型和name来决定是否处理这个task.
Tasks在一个独立的,从asp.net thread pool上的一个thread上执行.
Notifications
模块能够呈现message到admin UI上, 通过INotifier的实现的方法.
Localization
程序的Localization是通过包装string资源, <%: T("This string can be localized") %>.
Orchard的资源管理能够从PO文件中加载本地化资源.
Content Item的localization通过其它的方法:localized的content item是通过一个独立的part来实现的.
当前的culture是通过culture manager来决定的. 默认的是通过site settings配置的, 但是可以被user profile和browser's settings覆盖.
Logging
Logging是通过ILogger的实现来将日志存储不同的介质的.
Orchard Core
Orchard.Core assembly中包含了Orchard必须的modules. 其它的模块可以依赖于这些一定存在的模块.
core modules比如: feeds, navigation, routeable.
Modules
Orchard有一些内建的模块, 比如blogging, pages.
modules是一个asp.net mvc area 和manifest.txt文件, 用来扩展orchard.
module典型的包含handlers, content types和默认模板和admin UI.
modules当csproj文件有变动的时候,就能够被动态编译,
Themes
Orchard的设计的基本原则是所有的Html都是能够通过替换theme来替换的.
Orchard渲染的基础是Shapes. theme engine的工作是找到当前的theme和如何最好的渲染每个shape. 每个shape有个default渲染, 在module中的模板view文件夹或者代码中的shape方法中. default渲染能够被theme重写.
Themes可以有个parent.
Themes能够和modules一样包含代码, 能够有自己的csproj文件, 能够动态编译.
选择当前theme是通过IThemeSelector实现, 会返回一个theme name和针对request的priority. Orchard有4种实现IThemeSelector:
  • SiteThemeSelector使用在Site或者tenant中的设置, 优先级低.
  • AdminThemeSelector如果当前是admin URL, 使用admin theme. 优先级高
  • PreviewThemeSelector是如果当前是预览模式下使用预览的theme
  • SafeModeThemeSelector是只有当程序运行在"safe mode"的时候才使用的. 级别低.
theme selector的使用的一个例子是当发现请求是从mobile过来的,就是用mobile theme.

转载于:https://www.cnblogs.com/webenh/p/7691724.html

Orchard是如何工作的?相关推荐

  1. [翻译]Orchard如何工作

    Orchard一直是博主心中神一般的存在,由于水平比较菜,Orchard代码又比较复杂看了几次都不了了之了.这次下定决心要搞懂其工作原理,争取可以在自己的项目中有所应用.为了入门先到官网去学习一下相关 ...

  2. orchard文档之-orchard工作原理

    Orchard工作机制 创建一个 Web CMS (内容管理系统)与创建普通的web应用程序不一样.它更像是建造一个应用程序容器.当设计一个这样的系统时,可扩展性必须作为首要的特性. 这会是一个挑战, ...

  3. Orchard:如何生成Hello World模块

    在Orchard架构介绍中对Orchard的一些架构内容进行了介绍,下图是Orchard自带的一些模块, 本篇讲解一下如何扩展Orchard来生成我们的第一个模块. 介绍 Orchard构建在ASP. ...

  4. 2011年1月和2月blog汇总:Orchard、敏捷个人、英语

    一晃眼,2011年已经走了2个月了,今年的1/6时间已经过去了,每次进行blog汇总都是对自己这几个月所做事情的一个小结,由于过年1月份的blog没有汇总,就和2月份的一起汇总吧. ASP.NET 看 ...

  5. 1 Orchard 入门篇-Orchard 基本概念

    引言:最近学习Orchard,被它的各种机制彻底迷上了,有点相见恨晚的感觉,学习起来完全停不下来,工作10多年没写过1篇博客的我都忍不住开通博客,记录下自己使用Orchard做项目的点点滴滴.本系列连 ...

  6. Orchard架构介绍

    在如何使用Orchard搭建敏捷个人的网站(2)中 介绍了如何使用Orchard,但对于我们来说,更重要的是学习Orchard是如何架构的,如果我们自己编写一个类似应用该如何做.今天有空再次看看 Or ...

  7. Orchard Core 1.0.0 正式发布!

    James: Orchard 最早是微软的员工创造的开源项目,使用的技术架构可以说是非常优秀,源码值得学习.功能也非常强大,支持模块化.多租户.工作流等等功能,可以说是 .NET 世界的 WordPr ...

  8. 试翻译Output Cache Improvements in Orchard 1.9

    原文:http://www.ideliverable.com/blog/output-cache-improvements-in-orchard-1-9 Orchard1.9即将到来(我知道,已经&q ...

  9. orchard文档之-搜索和索引

    搜索和索引 Orchard提供了在应用程序中索引和搜索内容项的能力.可以启用Indexing特征来提供索引功能, ,同时也指定了具体的索引实现(默认是包含了基于Lucesne的实现). 除了 Inde ...

最新文章

  1. 信息安全系统设计基础第十一周学习总结
  2. zookeeperclient设置监听
  3. python编程100例画图-Python练习实例56 | 画图,学用circle画圆形
  4. java properties读取缓存_Java读取Properties文件
  5. 【Java】关于Java编程软件idea快捷键的使用
  6. 现实迷途 第八章 不轨企图
  7. 2022短视频去水印小程序源码+支持批量解析
  8. 局域网的分类:以太网、令牌环网、FDDI、ATM、WLAN
  9. c 语言图片转字符画,图片转化为字符画(C#版)
  10. 一起来找茬:记一起 clang 开启 -Oz 选项引发的血案
  11. 如何建立个人网站服务器篇
  12. ADM pro破解百度云限速 ADM pro设置方法 ES文件管理器
  13. Python开发《外星人入侵》游戏项目,付详细代码和注释
  14. 自学Vue之路——Vue介绍及基本语法
  15. .crx文件怎么解压
  16. [转]Flex 处理bmp图片as
  17. 全款房抵押贷款要注意什么?
  18. Varnish——CDN推送平台管理(web界面批量清除缓存)
  19. 禁用Windows10系统驱动程序强制签名的简单方法
  20. 机器学习 第三节 第十课

热门文章

  1. 【进阶修炼】——改善C#程序质量(9)
  2. Python 和 egg 文件
  3. asp.net2.0学习历程 菜鸟到中级程序员的飞跃[z转]
  4. 治理软件供应链安全要打“团体赛” 共同建立供应链安全体系
  5. 详细分析微软“照片”应用图像编码器漏洞 (CVE-2020-17113)
  6. 谷歌披露影响多个苹果操作系统的零点击Image I/O 漏洞和开源库 OpenEXR漏洞
  7. 14.12.1类的特殊成员1
  8. OKHTTP好文推荐
  9. SMB协议端口号,Windows文件共享协议
  10. 使用Xmanger登陆aix系统桌面时报桌面服务DT未启动问题