前面的博客介绍了:
博客园原文地址 :
这篇博客主要是讲模块的架构和加载,以及模块与DotNetNuke门户网站(Portals)系统的关系。充分了解模块可以帮助DNN开发者根据需要更清晰的构建模块。
在DNN中,模块是一个可插入的用户接口组件,用来处理请求并生成动态的内容。它只能出现在ASP.NET页面上,而页面可以包括任意数量的模块"实例"。
整个模块架构包括四个部分 : 门户网站(Portal),页面(Tab),模块(Module)和模块容器(Container)。
- 门户网站(Portal)
Portal可以定义为一个基于Web的应用程序,从不同的源聚集内容,并寄宿信息系统的表示层(模块)。下图描述了Portal的基本架构,DNN处理页面请求时需要执行许多步骤。下述步骤在页面初始化的过程中执行,用来在运行时动态地加载模块。动态创建的模块然后就能够处理它们自己的生存周期,包括诸如初始化、加载、呈现等各种事件。
图一 : Portal的基本架构
第一步: 页面配置检索(Page Configuration Retrieval)
第1步就是为被请求的页面检索模块。检索步骤由许多重要的信息块构成,例如页面上出现的各个模块、模块在页面上显示的区域(即内容窗格Pane),以及与每个模块相关联的安全角色。
//Default.aspx.cs //OnInit //load skin control and register UI js UI.Skins.Skin ctlSkin = UI.Skins.Skin.GetSkin(this); //add skin to page SkinPlaceHolder.Controls.Add(ctlSkin); //DotNetNuke.UI.Skins.Skin.cs : OnInit() bool success; //Load the Module Control(s) success = Globals.IsAdminControl() ? ProcessSlaveModule() : ProcessMasterModules(); //DotNetNuke.UI.Skins.Skin.cs : ProcessMasterModules() bool success = true; if (TabPermissionController.CanViewPage()) { //check portal expiry date if (!CheckExpired()) { if ((PortalSettings.ActiveTab.StartDate < DateAndTime.Now && PortalSettings.ActiveTab.EndDate > DateAndTime.Now) || TabPermissionController.CanAdminPage() || Globals.IsLayoutMode()) { //dynamically populate the panes with modules if (PortalSettings.ActiveTab.Modules.Count > 0) { foreach (ModuleInfo objModule in PortalSettings.ActiveTab.Modules) { success = ProcessModule(objModule); } }
第二步: 安全审计(Security Audit)
第2步就是判断在上一步中检索出来的安全信息。通过检查当前用户的角色(是注册用户还是匿名用户)以及与每个模块相关联的查看角色,就可以为当前页面形成一列经过“授权”的模块。
private Boolean ProcessModule(ModuleInfo module) { bool success = true; if (ModulePermissionController.CanViewModule(module) && module.IsDeleted == false && ((module.StartDate < DateTime.Now && module.EndDate > DateTime.Now) || Globals.IsLayoutMode() || Globals.IsEditMode())) { //... } //... }
第三步:内容注入(Content Injection)
第3步(也是最后一步)就是将“授权”模块动态地插入到页面上相应的内容窗格中。在所有的模块加载之后,每个模块就能够执行各自的事件并呈现内容。
Pane pane = GetPane(module); if (pane != null) { success = InjectModule(pane, module); }
- 页面(Tab)
图二描述了基本的Portal的Tab组件。页面本身表示一个完整的标记文档,由大量的内容窗格(Pane)组成,并且在每个内容窗格中还包含大量的模块。
图二:页面组件
每个模块都包含一个标题、若干装饰(Container)以及由模块生成的内容。装饰可以包括若干按钮、链接以及一个改变模块状态或者执行与模块相关功能的悬浮菜单。
- 模块(Module)
正如前面所述,Portal是基于Web的应用程序,处理各种请求并生成动态内容。每个模块都生成自己的标记块(称为段),再和皮肤的标记一起展示完整的文档。
因为每个模块都生成自己的标记,所以可以将模块视为较大应用程序中的微型应用程序。通常,用户通过单击链接或者提交表单(所提交的表单由门户网站系统及传递给相应模块的命令处理)与每个模块生成的内容交互。
- 模块容器(Container)
模块周围的装饰称为模块容器。通过容器,用户能够与模块交互,执行诸如最小化、最大化以及其他高级特性(如果用户拥有该页面的编辑特权)的动作。
图三示范了一个HTML模块在用户以编辑特权登录时的模块容器。这个模块容器包含许多项,例如拥有一列管理选项的悬浮菜单、模块的标题。
图三:模块容器