Orchard详解--第七篇 拓展模块(译)
2024-09-18 19:48:36
Orchard作为一个组件化的CMS,它能够在运行时加载任意模块。
Orchard和其它ASP.NET MVC应用一样,支持通过Visual Studio来加载已经编译为程序集的模块,且它还提供了自定义的模块加载策略,如允许加载没有部署到"~/bin"目录下的程序集模块。
另外,Orchard还支持直接部署源代码然后动态编译的功能,这个功能比这届部署二进制文件更灵活,而且还可以在一些适合的地方在不使用Visual Studio的情况下自定义代码,类似与ASP.NET的App_Code目录,但是Orchard支持多个独立的目录(一个模块一个)。
本章的目的是在技术层次描述Orchard如何加载模块,这个功能经常被认为是Orchard的动态编译,即使动态编译技术仅用于非常特殊的场景。
概述
当Orchard应用程序启动时,Orchard框架(确切的将是ExtensionloaderCoordinator)计算出那些模块被安装并激活它们(加载相应程序集)。
在顶层看来,这个过程主要有三个步骤:
- 查找:找出这个网站有那些模块。
- 激活:找出使用什么策略来加载这些模块。
- 解决引用依赖:找出哪些引用程序集用于激活模块。这个是激活部分,但是需要在这里就考虑如何处理模块的依赖问题。
搜索
Orchard通过搜索不同目录下的"module.txt"和"theme.txt"文件来获取到一个可用的拓展列表。这些目录主要有:
"~/Modules"目录
该目录下面包含了大量的Orchard模块,并约定每一个模块存放在一个以模块名称命名的子目录下,每一个目录下有一个"module.txt"文件,这个目录仅支持模块的打包、分配和共享。
"~/Core"目录
这个目录包含了一个"Orchard.Core"的程序集,该程序集中包含的模块是Orchard系统中的核心部分,这些模块不能像"~/Modules"目录下的模块那样自由修改。
"~/Themes"目录
这个目录下面包含了Orchard主题,关于动态编译,主题和模块基本类似,除了主题不需要代码。
自定义目录
在Orchard1.10版本中提供了新的功能,允许从自定义的目录下加载拓展模块。自定义的目录可以在AppSetting中配置。
例子
下面这个例子中Common和Localization是Core模块,Orchard.Azure和Orchard.Caching是内置的模块,SafeMode和TheAdmin是内置主题,MyModule1和MyModule2是自定义路径中的自定义模块,MyBase和MyTheme是自定义主题目录下的自定义主题。
激活
当Orchard收集到所有的"Module.txt"后,Orchard将使用不同策略来将这些模块加载到内存中。在程序内部,"加载模块"这个动作是一个以"module.txt"文件作为输入然后将一个类型为"System.Type"的列表作为输出的操作。这将比简单的返回一个"System.Assembly"更通用,这样Orchard可以支持在一个程序集中包含多个模块,如Orchard.Core.dll中包含了大约10个模块。
"引用模块"加载器
这个加载器查找"~/bin"目录下的和"module.txt"文件中指定模块名称一致的程序集,如果这个程序集存在,那么将这个模块加载然后返回它所有的类型。这个加载器用于通过"ASP.NET的方式"加载一些已经预编译好在"~/bin"目录下的程序集(注:这里一般是因为Orchard的根程序引用了其中某一些模块,以致于根程序编译时会将该程序集放置到~/bin目录下,这种情况ASP.NET就会自动加载该程序集,而加载器的功能主要用于获取该程序集的所有类型)。
"核心模块"加载器
如果"module.txt"文件是从"~/Core"目录下来的,那么CoreExtensionLoader将从Orchard.Core程序集的"Orchard.Core.<模块名称>"的命名空间下返回所有类型。Orchard.Core包含多个被称为核心的模块,它们在Orchard Framework上提供了一些基础功能。
"预编译模块"加载器
如果"module.txt"来自"~/Modules"目录,那么该加载器就会到"~/Modules/<ModuleName>/bin"目录下根据模块名称查找程序集文件,如果存在,那么将它复制到"~/App_Data/Dependencies"目录下,这个目录是一个特殊的目录,它用于ASP.NET应用程序在"~/bin"目录之外查找附加的程序集。
"动态模块"加载器
如果"module.txt"来自"~/Modules"目录,且在"~/Modules/<ModuleName>"目录下存在".csproj"文件,那么该加载器就会使用Orchard build manager编译这个.csproj文件,并返回该程序集的所有类型。
注:该加载器是Orchard中唯一一个使用"动态编译"的加载器,而且如果该模块已经预编译,那么它是可选的。
加载器二义性处理
因为有可能出现一个给定模块被多个加载器加载,所以Orchard有一个处理歧义的方法,如选择"正确的"加载器。每一个加载器在加载模块时都能够返回一个模块"最新修改时间"。对于一个给定模块,如果存在多个加载器,那么Orchard将选择返回的"最新修改时间"最近的加载器。
例如,一个给定模块即存在包含.csproj文件的源代码且bin目录下也存在编译好的程序集。模块的第一次加载,Orchard会加载"bin"目录下的程序集,虽然可能这个程序集不是最新的(代码编译后,代码被修改)。但是对于Orchard来说如果代码在编译后产生任何的修改,"动态模块"加载器将返回一个文件最近的修改时间(代码或csproj文件),然后Orchard将根据时间来选择正确的加载器(预编译加载器还是动态编译加载器)。
需要注意的是对于Core模块来说,它只有一种加载方式,所以不会出现二义性。
例子
禁用"动态模块"加载器
在生产环境应该禁用动态加载,因为生成环境不应该动态的安装、加载模块,而另一些原因是因为动态加载会创建很多FileSystemWatcher(影响性能)来检测模块变化。
禁用该加载器需要在HostComponents.config文件中加入以下内容:
然后部署该文件并重启应用池。
注:你必须检查每一个模块的bin目录是否已经存在编译后的程序集。
配置的变化检测
正如上面介绍的,Orchard应用程序在启动时将加载相关模块。然而一旦应用程序启动,可能会发生变化,如:可能安装新模块、手动改变源代码、删除模块等等。为了检测这些改变,Orchard让每一个加载器监控变化然后在发生变化时发送通知。
当变化被检测到,当前模块的配置将被废弃然后在应用程序再一次启动时重新验证、加载、激活模块。一些情况下,这些改变需要ASP.NET应用域重启(如新版本程序集的加载)。Orchard监听这些情况并强制重启ASP.NET应用程序域。
~/App_Data/Dependencies/Dependencies.xml文件
这个文件包含了模块的列表、这些模块的加载器和模块最后一次正确的引用配置,它是Orchard最后一次运行成功的所有模块的配置信息。它可以用于检查新版本模块是否被加载等等。
原文:
翻译这篇文档的原因是,它详细的对Orchard拓展模块加载内容进行了介绍,而接下来将从代码层面分析以上内容是如何实现的。
最新文章
- Web API 强势入门指南
- 收藏一些好用的fifo
- 线程,join合并线程
- Mac Pro 安装 Sublime Text 2.0.2,个性化设置,主题 和 插件 收藏
- Oracle手工建库
- PHP文本框的值随下拉框改变
- 在同一个机器上运行两个jboss修改配置
- HDU 5025 (BFS+记忆化状压搜索)
- golang为LigerUI编写简易版本web服务器
- [记录] web icon 字体
- 【网络流#4】UVA 753 最大流
- SQLSERVER图片查看工具SQL Image Viewer5.5.0.156
- scrollview嵌套gridview滑动问题
- ACCESS数据库增强器需求及介绍
- 集群通信组件Tribes之整体介绍
- Ajax全局处理错误
- 在绘图的时候import matplotlib.pyplot as plt报错:ImportError: No module named &#39;_tkinter&#39;, please install the python-tk package
- OSGI企业应用开发(十五)基于Spring、Mybatis、Spring MVC实现一个登录应用
- 【codeforces 870F】Paths
- 牛掰本机限速软件appband