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

时间:2012-02-24 03:15:45

标签: c# asp.net

我现在一直在谷歌搜索,也许我不是在寻找正确的术语。我想拥有一个能够加载/运行其他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应用程序。

2 个答案:

答案 0 :(得分:3)

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

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

考虑以下设想的例子:

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(不需要虚拟目录),它就可以正常工作。

答案 1 :(得分:2)

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应用程序类实现的接口,所以当你使用反射来创建这样一个类的实例时,你知道它实现了什么接口,并且可以执行其方法。

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