具有插件和多租户支持的 ASP.NET MVC 应用程序以及单独的 AppDomains?

Posted

技术标签:

【中文标题】具有插件和多租户支持的 ASP.NET MVC 应用程序以及单独的 AppDomains?【英文标题】:ASP.NET MVC application with plugin and multitenancy support with separate AppDomains? 【发布时间】:2012-04-26 07:15:13 【问题描述】:

问题

我有一个具有插件/模块架构多租户支持的 ASP.NET MVC 3 应用程序。 MEF 用于解决依赖关系和加载可插拔部件。

每个模块都由控制器、视图和其他对象组成(实际上它是一个程序集)。模块被加载到租户中。

简单的配置可能如下所示:

租户 1:

模块 A,版本 1.0 (ModuleA.dll) 模块 B,版本 1.0 (ModuleB.dll)

租户 2:

模块 B,版本 1.0 (ModuleB.dll)

不同模块和不同版本的 Dll 分别存储在不同的物理位置。 并且应用程序在一个 AppDomain 上运行(默认一个)。

但是,如果我们想在不同租户使用不同模块版本的情况下进行配置,我们会遇到在不同版本中加载相同程序集的问题。这意味着下面的场景不能完全正常工作,因为在从 ModuleB 解析类型期间,我们遇到了组合不匹配异常(版本 1.0 和 1.5 被加载到 MEF 中,但只有一个程序集被程序集加载器加载到 AppDomain 中)。

租户 1:

模块 A,版本 1.0 (ModuleA.dll) 模块 B,版本 1.0 (ModuleB.dll)

租户 2:

模块 A,版本 1.5 (ModuleB.dll)

解决方案?

因此我们提出了一种解决方案,即将不同的租户及其模块/程序集加载到单独的 AppDomain 中。这意味着从我们的示例中,Tenant1 和 Tenant2 被加载到 AppDomain1 和 AppDomain2 中。在 ASP.NET MVC 管道中,我们连接到控制器工厂以选择合适的应用程序域,如下所示:

请求默认处理 AppDomain(Web 应用程序启动的那个) 控制器工厂 从请求中获取 Tenant_Id 并从适当的 AppDomain 解析适当的控制器(我们有 Tenant_Id->Tenant->AppDomain 关系) 返回ControllerProxy(这是一个代理类,实现了IController并继承了MarshalByRefObject以便能够在不同的App Domians之间传递控制器) 动作调用者 在控制器代理对象上调用了适当的操作,现在执行发生在底层应用程序域中 在这里我们遇到了问题,因为动作调用程序无法将不可序列化的 RequestContext 传递给另一个应用程序域(换句话说,controllerProxy.Execute(RequestContext context) 正在引发关于序列化的异常)

问题:

如何以一种好的方式在应用域之间传递 RequestContext(不可序列化的对象)? 是否可以连接到管道中的另一个步骤以将执行重定向到底层应用程序域(在控制器工厂之前?) 或者有关于这个问题的其他解决方案的任何想法?

【问题讨论】:

【参考方案1】:

不可能。如果您尝试使用不同的 AppDomain,ASP.NET 会再次出现并困扰您。

相反,使用基于角色的授权来控制不同模块的访问。

我刚刚写了一篇关于 ASP.NET MVC3 中的插件系统的文章:http://blog.gauffin.org/2012/05/griffin-mvccontrib-the-plugin-system/

【讨论】:

问题是我们需要能够将不同版本的插件加载到不同的租户中(仍然在同一个 Web 应用程序中),据我了解,您描述的插件系统不能处理这种情况。还是? 不可能。不能在同一个 appdomain 中使用不同的程序集版本,由 ASP.NET 管理 AppDomain。如果您尝试使用其他应用程序域,您会后悔的。 实际上,您可以在同一个 appdomain 中使用不同的程序集版本 - 通过加载没有上下文的程序集 - 从字节数组 (Assembly.Load(byte[]))。我目前正在尝试使其正常工作,但 MEF 存在问题...【参考方案2】:

这并不能直接回答您关于 ASP.NET MVC 中的多个应用程序域的问题。但是,关于其他选项,您可能需要查看托管应用程序框架(又名 System.Addin)。它是 .NET Framework 的一部分,与 MEF 类似,它支持动态加载模块。但是,它内置了跨应用程序域拆分这些模块的功能。它可能更适合您的需求。不过,我不确定它与 ASP.NET MVC 的匹配度如何。

这个document on MSDN 应该让您开始使用 MAF。

【讨论】:

以上是关于具有插件和多租户支持的 ASP.NET MVC 应用程序以及单独的 AppDomains?的主要内容,如果未能解决你的问题,请参考以下文章

Orchard Core Framework:ASP.NET Core 模块化,多租户框架

jQuery Grid With ASP.Net MVC

用于具有单个回调 url 的多租户应用程序的 ASP.NET Core Google Auth?

具有 ASP.NET Core 3.0 和 EF Core 的多租户应用程序

RESTful 服务:WCF 与 ASP.NET MVC

在 ASP.NET Core WebApi 中处理多个租户