ASP.Net MVC:如何在没有AppPool重启/回收的情况下动态加载程序集(控制器)

时间:2013-05-01 01:59:33

标签: asp.net-mvc plugins module .net-assembly application-pool

我正在尝试为我正在处理的网站编写模块/插件系统。总体目标是:

  1. 每次添加新插件时都不需要重新编译主网站。
  2. 能够将DLL和CSHTML文件转储到一组文件夹中,这些文件夹基本上会添加一组路由,控制器和模块所依赖的任何其他程序集(实体框架等)。
  3. 避免将插件文件标记为“嵌入式资源” - 尤其是视图。
  4. 能够添加和删除这些模块/插件,而无需重新启动/回收IIS应用程序池或卸载应用程序域。
  5. 我按照Umbraco的例子来做#1-3工作。基本上,我使用PreApplicationStartMethod属性标记了一个方法,并在其中隐藏了复制DLL,并使用自定义ViewEngine来定位模块的CSHTML文件。当我的网站首次启动时,我的模块的控制器和视图正在运行,并且装配了程序集:Hooray!

    然而,当到了尝试第4部分时,我在调用BuildManager.AddReferencedAssembly()时收到此错误:

      

    此方法只能在应用程序的预启动期间调用   初始化阶段。使用PreApplicationStartMethodAttribute   声明将在该阶段中调用的方法

    到目前为止,这是一个非常令人沮丧的过程,我的直觉告诉我,这个错误意味着死路一条。是这种情况,还是有一个聪明的解决方法?

3 个答案:

答案 0 :(得分:0)

添加新模块时编辑web.config文件会导致网站重新编译。

您可以在脚本中自动执行此操作,强制将新的.dll复制到实时ASP.NET临时文件目录。

答案 1 :(得分:0)

查看便携式区域。基本上,常规MVC区域(包括视图,控制器等)被编译成单个dll。这些dll(每个区域一个)可以放入托管MVC网站,可以像任何其他MVC区域一样进行调用。

一些入门参考:

Portable Areas three years later – Part 5

MvcContrib Portable Areas

答案 2 :(得分:0)

“能够添加和删除这些模块/插件,而无需重新启动/回收IIS应用程序池或卸载应用程序域。”

事实证明,您无法从应用程序域卸载程序集。

How to unload an assembly from the primary AppDomain?