1

我正在构建一个 ASP.NET 网站,它将充当“框架”并显示有关在 Web 服务器上运行的某些服务的信息。站点需要做的一件事是为服务加载的某些模块提供自定义配置页面。这些模块都将实现一个通用 API,所以不用担心——我关心的是如何获得配置页面,这些页面对每个模块都是唯一的,由一个通用前端提供服务?

页面需要验证用户输入,处理按钮点击等。所以它并不像在每个模块上都有一个方法那么简单:

public string getHTMLConfigPage()

这仅在模块的配置页面不需要用户输入时才有效。在这种情况下,所有模块都需要某种形式的配置,至少需要一个指示“打开/关闭”的复选框

这是理想的用例:

  1. 在运行时,IIS 进程与后端服务对话并计算出有 N 个模块正在运行
  2. 服务器将这 N # 个模块的链接添加到下拉菜单中
  3. 当用户单击某个模块的菜单项时,将显示该模块的配置页面
  4. 用户可以根据自己的意愿配置模块,单个模块控制整个序列

我们已经在 C# winforms 中成功实现了这一点。我们这样做的方式是让每个模块实现一个方法public void showConfigDialog(IWin32Window parent);。这适用于常规桌面应用程序——但显然不能帮助我对 Web 服务器做任何事情。

到目前为止,我唯一想到的是让每个模块也安装一些东西到 IIS Web 服务器上,然后只做一个iFrame主“框架”页面可以在框架中显示模块页面的地方(或弹出窗口),但这似乎很混乱,因为模块开发人员必须包含某种设置脚本才能将东西放入 IIS 空间......

那么 - 有没有更好的方法来做到这一点,或者 iFrame 方法是唯一的方法?

系统详情:

  • ASP.NET 4.0
  • C# .NET 4.0
  • IIS 7.5(服务器 2008 R2)

编辑:附加细节

我还考虑过让模块将一个特殊的 ASP.NET DLL 放在 ASP.NET 将在运行时探测的目录中。但问题的根源仍然存在——模块提供的 DLL 如何集成到主要的网页集中?主要的网页集有一个Site.Master页面,提供一些必需的项目(CSS、菜单栏、一些 jQuery 插件等)。来自模块的 DLL 可能需要此信息以及主网页用来与我们编写的底层 Windows 服务对话的命名管道。

4

4 回答 4

3

听起来您需要一个用于 ASP.NET 的插件框架。您可以通过使用 MEF(托管扩展框架)来实现这一点,它允许您将复杂的页面和配置放入插件并在运行时加载它;或者我相信。

首先在这里查看 Code Project 文章这里可能还有 MSDN 示例。

于 2012-12-26T10:13:41.613 回答
1

您描述的大部分内容都在 Orchard CMS 中实现。http://orchardproject.net。您可能会考虑将他们的代码作为如何完成此动态模块加载的示例,或者如果可能的话只是切换到 Orchard 作为您的应用程序的框架。它被称为 CMS,但实际上它是一个很好的框架,可以在其上构建 .NET 应用程序。

他们使用 Autofac 进行依赖注入,模块可以通过实现接口来注入自己的 Routes、Content、Pages 等。Orchard 的核心框架会扫描这些模块以查找实现特定接口的类,然后调用这些接口上的方法以从模块中提取特定内容。您可以从命令行或 Web 界面启用/禁用模块。

例如,我可以创建一个模块,然后在其中我将有一个类实现一个名为的接口,该接口INavigationProvider具有 Orchard 用于获取管理仪表板的菜单项的方法。然后我可以IRouteProvider在另一个类中实现接口,它告诉 Orchard 我的应用程序的所有路由(前端和管理仪表板)。您还可以对视图/控制器/路由使用 MVC 约定。支持 Razor 和 WebForms 视图引擎。

于 2012-12-28T16:55:23.583 回答
0

如果您有明确定义的不同场景,我认为处理来自其他类中的页面或来自另一个嵌入项目或库的数据不是问题。例如,要填充 DropDownList 中的数据,您可以执行以下操作:

Partial Class Default
  Inherits System.Web.UI.Page

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      If Not Page.IsPostBack Then
          Dim itemList As List(Of ListItem) = ClassForTheMagic.GetItemsForComboBox(txtBox1.Text, checkBox2.check, ...)
          For Each item As ListItem In itemList
              DropDownList1.Items.Add(item)
          Next
      End If
  End Sub

结束类

然后,您可以在其他文件中:

Public Class ClassForTheMagic

  Public Shared Function GetItemsForComboBox(ByVal txtBox1 As String, ByVal checkBox2 As Boolean, ...) As List(of ListItem)
      Dim itemList As New List(Of ListItem)
      itemList.Add(New ListItem(txtBox1, "..."))
      itemList.Add(New ListItem(checkBox2, "..."))
      ...
      Return itemList
  End Function

End Class

ps:对不起vb代码

于 2012-12-06T23:22:59.957 回答
0

我会建议:

  • 具有相互结构访问的基线插件结构模型,因此插件主机将能够实例化/初始化各个插件,并将其自身(或模型类的选择)作为参考传递。
  • HTTP 模块,用于迭代加载的插件并推送上下文页面,以便它们可以由管道模型中的插件处理。这样,您甚至可以选择在特定时刻触发的特定事件 - 例如,在用户键入电子邮件后触发对 Gravatar 图标/OpenID 身份验证的搜索,并将收集到的数据发布到插件主机提供的模型类上.
于 2012-12-27T21:10:17.423 回答