简体   繁体   English

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

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

I've been googling for a bit now, and maybe I'm not searching for the correct term. 我现在一直在谷歌搜索,也许我不是在寻找正确的术语。 I want to have a single "shell" asp.net web application that is able to load/run other web applications (much like prism does with Silverlight xap files). 我想拥有一个能够加载/运行其他Web应用程序的“shell”asp.net Web应用程序(就像prism对Silverlight xap文件一样)。 However, I can't seem to find any verbage other than "sub projects", which require one to add the project to the solution. 但是,除了“子项目”之外,我似乎无法找到任何其他版本,这需要将项目添加到解决方案中。 I simply want to drop WebApplicationB.dll into the Bin folder and have ShellWebApplication load the dll and display the default page in an iframe or something. 我只是想将WebApplicationB.dll放到Bin文件夹中,让ShellWebApplication加载dll并在iframe中显示默认页面。

How can this be done or where can I find information on how this can be done? 如何做到这一点或在哪里可以找到有关如何做到这一点的信息?

Update: Offering a bounty to someone who can show code or point me to a sample project that shows how this can be done. 更新:向可以显示代码或指向我的示例项目的人提供奖励,以显示如何完成此操作。 Want to be able to "load" another asp.net web site/web application and its dependencies (dll or no) AND display that loaded asp.net web application's default.aspx start page without altering a Visual Studio solution that already contains the shell asp.net web application. 希望能够“加载”另一个asp.net网站/ Web应用程序及其依赖项(dll或no)并显示加载的asp.net Web应用程序的default.aspx起始页面,而不更改已包含shell的Visual Studio解决方案asp.net Web应用程序。

This is actually fairly trivial to accomplish; 这实际上是相当微不足道的; we do it. 我们做到了。

The main key is that your "modules" should either have their own content folders or you need to be careful not to have the exact same file names at the same location. 主要关键是您的“模块”应该有自己的内容文件夹,或者您需要注意不要在同一位置具有完全相同的文件名。

Consider the following contrived example: 考虑以下人为的例子:

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.  

With this structure you'll be able to copy both web applications into the same target directory. 使用此结构,您将能够将两个Web应用程序复制到同一目标目录中。 Due to how .Net functions this will work just fine and both will be executed within the same process space. 由于.Net功能如何正常工作,两者都将在同一个进程空间内执行。

Of course, you need a way for the Shell to know about Module 1. And you want to be able to deploy Shell without Module1. 当然,您需要一种方法让Shell了解模块1.您希望能够在没有Module1的情况下部署Shell。 The best way here is to add an assembly project that contains the interface definition you need. 这里最好的方法是添加一个包含所需接口定义的程序集项目。 You add a reference to this project to both Shell and Module 1. Something like: 您将此项目的引用添加到Shell和Module 1.类似于:

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

Where IAppModule.cs looks something like: IAppModule.cs看起来像这样:

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

MenuOption.cs looks something like: 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
}

The PluginFactory.cs is similar to: PluginFactory.cs类似于:

public sealed class PluginFactory {
  PlugingFactory() { }

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

The purpose of GetMenu here is to return a collection of references to the available pages in the module. GetMenu的目的是返回模块中可用页面的引用集合。

Inside Module1 you would implement the interface like: 在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;
  }
}

So, at this point we have 2 web app projects and 1 assembly project. 因此,此时我们有2个Web应用程序项目和1个组装项目。 The web app projects don't know anything about each other. Web应用程序项目彼此之间不知道任何事情。

The next step is to tell the Shell that Module1 exists. 下一步是告诉Shell,Module1存在。 We do this by having a database table of available modules. 我们通过提供可用模块的数据库表来实现这一点。 You could do the same thing in a web.config file. 您可以在web.config文件中执行相同的操作。 The main thing is that the shell project needs the Type Name and reference to Module 1's AppModule class. 主要的是shell项目需要Type Name并引用Module 1的AppModule类。 For example: " Module1.AppModule, Module1 " 例如:“ Module1.AppModule, Module1

Then, inside your shell master page you can do something like: 然后,在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...

  }
}

For bonus points, we have a Master page in the root of our shell project called "Main.master" Each of our modules also has a "Main.master" master page in their root. 对于奖励积分,我们在shell项目的根目录中有一个名为“Main.master”的Master页面。我们的每个模块的根目录中都有一个“Main.master”母版页。 The ones in the modules have the build action set to none and copy to output set to Do not copy. 模块中的那些将构建操作设置为none,并将复制到输出设置为Do not copy。

The master page is where we actually load the menu options. 母版页是我们实际加载菜单选项的地方。 Also, all of the other masters within each module inherit from this primary one. 此外,每个模块中的所有其他主服务器都继承自此主模块。 Interestingly, descendent master pages don't care about the actual "type" of the parent, just the location of that page. 有趣的是,后代母版页并不关心父母的实际“类型”,只关心该页面的位置。 This means you can control your main master page from the shell and have each module "inherit" that simply by NOT deploying their overall master page. 这意味着您可以从shell控制主母版页,并让每个模块“继承”,只需通过NOT部署其整体母版页即可。

For example: 例如:

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.

Because of how master page inheritence works, the Module1.master file refers to it's parent by "~/main.master". 由于母版页继承的工作方式,Module1.master文件通过“〜/ main.master”引用它的父级。 By not deploying the modules main.master and instead just deploying the shell's main.master we are given a LOT of flexibility. 通过不部署模块main.master而只是部署shell的main.master,我们获得了很大的灵活性。

At the end, you can deploy the shell project onto an IIS server. 最后,您可以将shell项目部署到IIS服务器上。 Later you can deploy ModuleX right on top of the shell project (no virtual directories needed) and it will just work. 稍后您可以在shell项目的顶部部署ModuleX(不需要虚拟目录),它就可以正常工作。

The dll contains the compiled code of your web application. 该DLL包含Web应用程序的已编译代码。 There is no point in 'loading the dll'. “加载dll”没有意义。 You probably want to load a control or a page, then let the user navigate to another page or control within this application which its code also contained in this dll. 您可能想要加载控件或页面,然后让用户导航到此应用程序中的其他页面或控件,其代码也包含在此dll中。 So there are a few options for you: 所以有几个选项:

  1. Use an iframe and point it to load a page of the other web application. 使用iframe并指向它以加载其他Web应用程序的页面。 This will load the dll of that application in order to execute the code behind of that page. 这将加载该应用程序的DLL以执行该页面后面的代码。 You can let the user navigate from that page to other pages of the application. 您可以让用户从该页面导航到应用程序的其他页面。

  2. Put a link in the shell application that when clicked will navigate the user to a page of the other application. 在shell应用程序中放置一个链接,单击该链接时会将用户导航到另一个应用程序的页面。 Again, the dll of the other application will be loaded in order to execute the code behind of that page. 同样,将加载另一个应用程序的DLL以执行该页面后面的代码。

  3. Load a user control of the other application dynamically. 动态加载其他应用程序的用户控件。 In your shell application you can have Page.LoadControl and then add the control to some place holder in your shell application. 在shell应用程序中,您可以使用Page.LoadControl,然后将控件添加到shell应用程序中的某个占位符。 The dll of the other application will be loaded in order to execute the control's code behind. 将加载另一个应用程序的DLL以执行后面的控件代码。 The Page.LoadControl requires you to give the a URL to the ASCX file. Page.LoadControl要求您提供ASCX文件的URL。 You can put this URL in your web.config file or in your database and can load different controls (which can also be controls of different applications) in your shell application. 您可以将此URL放在web.config文件或数据库中,并可以在shell应用程序中加载不同的控件(也可以是不同应用程序的控件)。

  4. Use reflection to dynamically create objects of classes of the other application. 使用反射动态创建其他应用程序的类的对象。 If you do so, you would probably want your shell application to introduce an interface which can be implemented by classes of other web applications, so when you use reflection to create an instance of such a class, you know what interface it implements, and can execute its methods. 如果你这样做,你可能希望你的shell应用程序引入一个可以通过其他Web应用程序类实现的接口,所以当你使用反射来创建这样一个类的实例时,你知道它实现了什么接口,并且可以执行它的方法。

The two first options are the easiest, the two other options are more advanced and are more powerful. 两个第一选项是最简单的,另外两个选项更先进,更强大。 If you give some more information about your use case perhaps I can recommend what would best fit. 如果您提供有关您的用例的更多信息,也许我可以推荐最适合的用例。

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

相关问题 如何发现绑定配置以在Web服务中进行身份验证 - How discover the binding configuration to authenticate in web service 如何在ASP.NET Web API应用程序中从另一个方法调用一个异步方法 - How to call one async method from another one in ASP.NET Web API application 如何发现应用程序的主要可执行文件 - How to discover the main executable file of an application 如何将数据从一页发送到另一页,使得该页无法导航C#Web应用程序 - How To Send Data From One Page To Another Such That Page Do Not Navigate C# Web Application 如何在ASP.NET MVC 4 Web应用程序中从一个控制器的视图重定向到另一个控制器的视图 - How to redirect to a View of another Controller from one Controller's View in ASP.NET MVC 4 Web Application 如何调试通过其他Web应用程序访问的Web应用程序? - How to debug a web application accessed through another web application? Web应用程序页面加载 - Web application page load 如何通过扫描LAN C#自动发现Web服务 - How to automatically discover Web Service by scanning LAN C# 如何在应用程序运行时发现新的MEF部件? - How to discover new MEF parts while the application is running? 如何在另一个应用程序的单元测试中读取Web应用程序配置文件 - How to read web application config file in unit test in another application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM