C# 多租户ASP.NET应用程序中的隔离

C# 多租户ASP.NET应用程序中的隔离,c#,.net,asp.net,appdomain,multi-tenant,C#,.net,Asp.net,Appdomain,Multi Tenant,我正在构建一个多租户ASP.NET应用程序。鉴于每个租户都可以动态配置其应用程序(这可能涉及将动态自定义程序集加载到内存中),我需要一种隔离每个租户的方法 出于维护原因,我不希望为每个租户创建新的Web应用程序 我一直在考虑使用AppDomainManager为每个应用程序创建一个AppDomain,但这似乎不适用于ASP.NET应用程序 有人对这个问题有什么建议吗 谢谢。我想问题是:如果您不喜欢创建Web应用程序,那么您真正可以接受的隔离类型是什么 如果您真的想要一个操作系统级的保证,即程序集

我正在构建一个多租户ASP.NET应用程序。鉴于每个租户都可以动态配置其应用程序(这可能涉及将动态自定义程序集加载到内存中),我需要一种隔离每个租户的方法

出于维护原因,我不希望为每个租户创建新的Web应用程序

我一直在考虑使用AppDomainManager为每个应用程序创建一个AppDomain,但这似乎不适用于ASP.NET应用程序

有人对这个问题有什么建议吗


谢谢。

我想问题是:如果您不喜欢创建Web应用程序,那么您真正可以接受的隔离类型是什么

如果您真的想要一个操作系统级的保证,即程序集不会互相践踏,我会为每个程序集提供它们自己的Web应用程序。如果您允许人们加载第三方程序集,这一点尤其正确;如果这些第三方程序集能够找到实例化非托管代码的方法,这一点尤其正确


如果全部是您的(托管)代码,我可以看到不创建单独的Web应用程序,但一旦您将动态自定义程序集放入混合中,我认为这是唯一的方法。

当您创建不同的网站时,您的URL根肯定会改变。我在想,为什么不将不同的应用程序放在主应用程序中,并在需要时将它们放在不同的应用程序池中

一。。。这样,根URL将保持不变。 两个。。。创建VDir或应用程序实例。哪一个需要动态? 三。。。我没有专业知识


如果我必须共享页面,[基于托管在不同VDir中的应用程序],我会为所有共享页面创建一个新的VDir。并使用一些自定义代码来显示与应用程序相关的数据。

我在MVC2中编写了多租户web应用程序。添加/删除帐户与在表中添加/删除行一样复杂,因为我选择了共享数据库、共享模式方法

这是一篇关于MSDN中多租户数据库设计的非常好的文章:

在MVC中,我所要做的就是正确设置路由,因此路径的第一部分是帐户名:

  • www.yourdomain.com/Account1/
  • www.yourdomain.com/Account2/
  • www.yourdomain.com/Account3/
我有一个自定义MvcHandler,用于查找每个请求的帐户:

public class AccountMvcHandler : MvcHandler
{
    public AccountModel Account { get; set; }

    public AccountMvcHandler(RequestContext requestContext)
        : base(requestContext)
    {
    }

    protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
    {
        string accountName = this.RequestContext.RouteData.GetRequiredString("account");
        Account = ServiceFactory.GetService<IAccountService>().GetAccount(accountName);

        // URL doesn't contain valid account name - redirect to login page with Account Name textbox
        if (Account == null)
            httpContext.Response.Redirect(FormsAuthentication.LoginUrl);

        return base.BeginProcessRequest(httpContext, callback, state);
    }
}
公共类帐户MvcHandler:MvcHandler
{
公共帐户模型帐户{get;set;}
公共帐户MVChandler(请求上下文请求上下文)
:base(请求上下文)
{
}
受保护的重写IAsyncResult BeginProcessRequest(HttpContextBase httpContext、AsyncCallback回调、对象状态)
{
string accountName=this.RequestContext.RouteData.GetRequiredString(“帐户”);
Account=ServiceFactory.GetService().GetAccount(accountName);
//URL不包含有效的帐户名-重定向到帐户名文本框的登录页面
如果(帐户==null)
httpContext.Response.Redirect(FormsAuthentication.LoginUrl);
返回base.BeginProcessRequest(httpContext、回调、状态);
}
}

正如安德烈亚斯·保尔森(Andreas Paulsson)所说,关键短语是“定制组件”。为什么配置需要“自定义程序集”?您正在使用CodeEmit吗?用户会上传它们吗?我宁愿考虑使用<强> Windows工作流基础< /强>任何特定于客户端的业务逻辑定制。

第二,关键短语是“自定义程序集”。好,我当然愿意考虑这一点,但我有一些担忧。第一,应用程序都应该有相同的根URL…这可能吗?第二,创建和删除需要是自动的…我应该使用WMI吗?我不知道我是怎么想的。。。IIs到底支持多少个Web应用程序?由于操作系统的局限性,这会在硬件云中扩展吗?三-我们希望此解决方案与Azure兼容(但不是特定于Azure),那么我将如何为Azure管理它?另外,您建议如何处理共享资源(页面)?一个从共享DLL中提取页面的VirtualPathProvider?我实际上已经设置了租户特定的MVC路由,这些路由工作得很好。自定义程序集的目的是租户必须能够使用自定义页面和代码来自定义其“实例”。为此目的隔离任何自定义代码是关键。为了进一步澄清,是的,用户将上载自定义程序集,这些程序集将在应用程序域中编译和运行。问题是这些程序集需要某种形式的隔离,以便无法访问来自其他租户的数据。我已经有了阻止自定义程序集进行DB调用的代码,但我关心的是静态上下文,例如应用程序状态或静态属性/方法/字段。我考虑过为这些自定义程序集动态创建应用程序域,但我更喜欢集成的程序,因为asp.net已经在为我管理应用程序域。另外,我不确定如何将我的自定义应用程序域引入asp.net请求生命周期(能够发布呈现的aspx页面)@JeffN825-允许用户上传任何代码是一个潜在的蠕虫。根据自定义客户端的数量,您可能希望为它们提供一个新的网站-这应该可以通过简单的msbuild脚本实现…我真的不想养成为每个新客户端都要求自定义部署的习惯。这确实是一个蠕虫的罐头,但肯定是需求的一部分。我一直在研究使用DLR来承载代码,但我不确定是否有足够成熟的实现来支持这一点。不过,问题是我如何动态创建应用程序?如果您使用的是IIS 7,您可以将IIS虚拟目录的配置委托给您的最终用户,以便他们可以进行配置