繁体   English   中英

如何发现和加载一个Web应用程序到另一个?

[英]How to discover and load one web application into another?

我现在一直在谷歌搜索,也许我不是在寻找正确的术语。 我想拥有一个能够加载/运行其他Web应用程序的“shell”asp.net Web应用程序(就像prism对Silverlight xap文件一样)。 但是,除了“子项目”之外,我似乎无法找到任何其他版本,这需要将项目添加到解决方案中。 我只是想将WebApplicationB.dll放到Bin文件夹中,让ShellWebApplication加载dll并在iframe中显示默认页面。

如何做到这一点或在哪里可以找到有关如何做到这一点的信息?

更新:向可以显示代码或指向我的示例项目的人提供奖励,以显示如何完成此操作。 希望能够“加载”另一个asp.net网站/ Web应用程序及其依赖项(dll或no)并显示加载的asp.net Web应用程序的default.aspx起始页面,而不更改已包含shell的Visual Studio解决方案asp.net Web应用程序。

这实际上是相当微不足道的; 我们做到了。

主要关键是您的“模块”应该有自己的内容文件夹,或者您需要注意不要在同一位置具有完全相同的文件名。

考虑以下人为的例子:

Shell
  \default.aspx
  \login.aspx
  \Images          <- images used by shell
  \css             <- primary CSS files
  \Pages\Accounts  <- all of the account editing pages here.

Module1
  \Module1\Pages       <- web pages specific to Module 1 
  \Module1\Images      <- images specific to module 1
  \CSS\Module1.css     <- Optionally, you can place the Module 1 CSS file into the main CSS directory.  

使用此结构,您将能够将两个Web应用程序复制到同一目标目录中。 由于.Net功能如何正常工作,两者都将在同一个进程空间内执行。

当然,您需要一种方法让Shell了解模块1.您希望能够在没有Module1的情况下部署Shell。 这里最好的方法是添加一个包含所需接口定义的程序集项目。 您将此项目的引用添加到Shell和Module 1.类似于:

Core
  \ObjectModel\MenuOption.cs
  \Extension\IAppModule.cs
  \Extension\PluginFactory.cs

IAppModule.cs看起来像这样:

public interface IAppModule {
  Collection<MenuOption> GetMenu( );
}

MenuOption.cs看起来像:

public class MenuOption {
  public string Href { get; set; } // url the option goes to
  public string Title { get; set; } // display name of the menu option
}

PluginFactory.cs类似于:

public sealed class PluginFactory {
  PlugingFactory() { }

  public static IAppModule LoadPlugin( string typeName ) {
    Type theType = Type.GetType(typeName);
    return (IAppModule)Activator.CreateInstance(theType);
  }
}

GetMenu的目的是返回模块中可用页面的引用集合。

在Module1中,你将实现如下界面:

public class AppModule : IAppModule {
  public Collection<MenuOption> GetMenu() {
    Collection<MenuOption> result = new Collection<MenuOption>();
    result.add(new MenuOption() { Href = "~/Module1/Pages/AccountList.aspx", Title="Account List"});
    result.add(new MenuOption() { Href = "~/Module1/Pages/NewAccount.aspx", Title="New Account"});

    return result;
  }
}

因此,此时我们有2个Web应用程序项目和1个组装项目。 Web应用程序项目彼此之间不知道任何事情。

下一步是告诉Shell,Module1存在。 我们通过提供可用模块的数据库表来实现这一点。 您可以在web.config文件中执行相同的操作。 主要的是shell项目需要Type Name并引用Module 1的AppModule类。 例如:“ Module1.AppModule, Module1

然后,在shell主页面中,您可以执行以下操作:

protected void LoadMenu() {
  // get list of available modules, just assuming mdules is string[] 
  foreach(String moduleId in moduleIds) {
    IAppModule module = PluginFactory.LoadPlugin(moduleId);    // now you have a reference to the module
    Collection<MenuOption> options = module.GetMenu();
    // and now we have all of the menu options for that module...

  }
}

对于奖励积分,我们在shell项目的根目录中有一个名为“Main.master”的Master页面。我们的每个模块的根目录中都有一个“Main.master”母版页。 模块中的那些将构建操作设置为none,并将复制到输出设置为Do not copy。

母版页是我们实际加载菜单选项的地方。 此外,每个模块中的所有其他主服务器都继承自此主模块。 有趣的是,后代母版页并不关心父母的实际“类型”,只关心该页面的位置。 这意味着您可以从shell控制主母版页,并让每个模块“继承”,只需通过NOT部署其整体母版页即可。

例如:

Shell
  /main.master  <- includes the basic CSS references, content structure and loads the various menus.

Module1
  /main.master  <- this file will NEVER be deployed and is only here to aid in testing the module independently of the shell
  /Module1/Module1.master <- inherits from main.master, adding other common elements for the module.

由于母版页继承的工作方式,Module1.master文件通过“〜/ main.master”引用它的父级。 通过不部署模块main.master而只是部署shell的main.master,我们获得了很大的灵活性。

最后,您可以将shell项目部署到IIS服务器上。 稍后您可以在shell项目的顶部部署ModuleX(不需要虚拟目录),它就可以正常工作。

该DLL包含Web应用程序的已编译代码。 “加载dll”没有意义。 您可能想要加载控件或页面,然后让用户导航到此应用程序中的其他页面或控件,其代码也包含在此dll中。 所以有几个选项:

  1. 使用iframe并指向它以加载其他Web应用程序的页面。 这将加载该应用程序的DLL以执行该页面后面的代码。 您可以让用户从该页面导航到应用程序的其他页面。

  2. 在shell应用程序中放置一个链接,单击该链接时会将用户导航到另一个应用程序的页面。 同样,将加载另一个应用程序的DLL以执行该页面后面的代码。

  3. 动态加载其他应用程序的用户控件。 在shell应用程序中,您可以使用Page.LoadControl,然后将控件添加到shell应用程序中的某个占位符。 将加载另一个应用程序的DLL以执行后面的控件代码。 Page.LoadControl要求您提供ASCX文件的URL。 您可以将此URL放在web.config文件或数据库中,并可以在shell应用程序中加载不同的控件(也可以是不同应用程序的控件)。

  4. 使用反射动态创建其他应用程序的类的对象。 如果你这样做,你可能希望你的shell应用程序引入一个可以通过其他Web应用程序类实现的接口,所以当你使用反射来创建这样一个类的实例时,你知道它实现了什么接口,并且可以执行它的方法。

两个第一选项是最简单的,另外两个选项更先进,更强大。 如果您提供有关您的用例的更多信息,也许我可以推荐最适合的用例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM