在 asp.net mvc 3 中管理每个会话和请求的 AutoFac 生命周期范围

2023-11-22

我想在 Web 应用程序中使用 AutoFac。我有根容器、每个会话一个子容器和每个请求一个子容器。我试图找出管理这些生命周期范围的最佳方法。在 Global.asax.cs 中我添加了以下内容:

protected void Application_Start(object sender, EventArgs e)
{
    var container = ...;
}

protected void Session_Start(object sender, EventArgs e)
{
    var sessionScope = container.BeginLifetimeScope("session");

    Session["Autofac_LifetimeScope"] = sessionScope;
}

protected void Application_BeginRequest(object sender, EventArgs e)
{
    var sessionScope = (ILifetimeScope) Session["Autofac_LifetimeScope"];
    var requestScope = sessionScope.BeginLifetimeScope("httpRequest");

    HttpContext.Current.Items["Autofac_LifetimeScope"] = requestScope;
}

protected void Application_EndRequest(object sender, EventArgs e)
{
    var requestScope = (ILifetimeScope)HttpContext.Current.Items["Autofac_LifetimeScope"];
    requestScope.Dispose();
}

protected void Session_End(object sender, EventArgs e)
{
    var sessionScope = (ILifetimeScope)Session["Autofac_LifetimeScope"];

    sessionScope.Dispose();
}

protected void Application_End(object sender, EventArgs e)
{
    container.Dispose();
}
  1. 如何告诉 AutoFac 使用我的 requestScope 作为获取依赖项的起点,以便我注册为 InstancePerLifetimeScope 的实现将使用我的 requestScope 进行解析?

  2. 如果这是不可能的,我可以让 AutoFac 在我的 sessionScope 之外创建其每个请求的生命周期范围吗?

  3. 或者我在这里走错了路?是否有其他方法可以让 AutoFac 意识到这个层次结构?

任何帮助或其他评论表示赞赏。


回应史蒂文.

我仍处于原型设计的早期阶段,但 sessionScope 中可能有以下内容:

  • 用户偏好
  • 身份验证和授权上下文(例如用户身份和角色)

与我要构建的应用程序无关,但在电子商务环境中,购物车可以是会话范围的。这可能是最好的具体例子。您期望它的生存时间比请求长,但比应用程序短。

可能不止这些,但如果我有一个针对 UserPreferences、身份验证和授权的策略,那么该策略也可以应用于稍后创建的其他组件。

一种可能的替代方法是在请求开始时获取所有必要的信息,并将这些配置的组件放入请求范围中。它会给我预期的结果,但它与我心中关于应用程序->会话->请求层次结构的模型不匹配。我希望创建一个有意义的系统,因为我绝对不是维护它的人。


你需要做的是实现你自己的Autofac.Integration.Mvc.ILifetimeScopeProvider。该接口控制请求生命周期范围的生成方式/位置。默认的,Autofac.Integration.Mvc.RequestLifetimeScopeProvider,根据每个请求处理生命周期范围的创建、处置和维护。

您可以浏览代码RequestLifetimeScopeProvider here,如果您打算这样做,我强烈建议您这样做。这是我能想到的最好的示例,其中包含显示这些事情之一的责任的工作代码。

您的实施ILifetimeScopeProvider将是您获取会话子容器、从中生成请求容器的位置,并在请求结束时清理请求容器。如果会话容器不存在,您可能还想在其中创建它。处理会话容器的清理/处置可能会很棘手,但从设计的角度来看,如果它全部集中在一个地方而不是部分在提供程序中、部分在应用程序类中,那就太好了。

一旦你有了你的ILifetimeScopeProvider当您设置依赖项解析器时,您将使用它。

var scopeProvider = new MyCustomLifetimeScopeProvider(container, configAction);
var resolver = new AutofacDependencyResolver(container, scopeProvider);
DependencyResolver.SetResolver(resolver);

关于会话级作用域概念的几句话警告:

  1. 您的内存占用可能会很大。您最终将获得系统上每个用户的生命周期范围。虽然请求生命周期很快就会弹出并消失,但这些会话级作用域可能会存在很长时间。如果您有很多会话范围的项目,那么每个用户都会有相当大的内存使用量。如果人们在没有正确退出的情况下“放弃”他们的会话,那么这些东西的生存时间就会更长。
  2. 生命周期范围及其内容不可序列化. 查看 LifetimeScope 的代码,没有标记[Serializable]...即使是,存在于其中的已解析对象也不一定全部标记为可序列化。这很重要,因为这意味着您的会话级生命周期范围可能在具有内存会话的单个机器上工作,但如果您部署到具有 SQL 会话或会话服务的场,事情就会崩溃,因为会话无法序列化你的存储范围。如果您选择不序列化范围,那么跨计算机的每个用户都有不同的范围 - 这也是一个潜在的问题。
  3. 会议并不总是补充水分。如果正在访问的处理程序(例如,Web 表单)未实现IRequiresSessionState,会话不会再水化(无论是否在进程中)。网络表格和MvcHandler默认情况下实现它,这样您就不会看到任何问题,但如果您有需要注入的自定义处理程序,您会遇到一些障碍,因为这些请求不存在“会话”。
  4. Session_End 并不总是触发. 根据 SessionStateModule.End 上的文档,如果您使用进程外会话状态,您实际上不会获得 Session_End 事件,因此您将无法进行清理。

考虑到这些限制,通常最好尝试远离会话存储范围。然而...如果这就是你要做的,那么ILifetimeScopeProvider就是这样做的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 asp.net mvc 3 中管理每个会话和请求的 AutoFac 生命周期范围 的相关文章

  • Unity3D StartCoroutine 调用一个函数,该函数什么时候返回?

    我知道Unity3D StartCoroutine调用了一个与StartCoroutine在同一线程上运行的函数 但是被调用的函数什么时候返回到原始调用者 我在互联网上查找了一个很好的 Unity3D Coroutine 示例 但找不到完整
  • MVC 重定向到没有控制器的视图

    希望应该是一个简单的 我创建了一个通用错误视图 当整个站点的操作方法内发生异常时 我想显示该视图 我创建了一个部分页面 所有导航都位于其中 因此我不需要在此视图上使用控制器 那么如何从控制器内的操作方法重定向到它 像这样的东西 HttpPo
  • 扫描文本文件时如何跳过行?

    我想扫描一个文件并在阅读之前跳过一行文本 我试过 fscanf pointer n struct test i j 但这个语法只是从第一行开始 我可以使用 scanf 使用以下指令跳过行 fscanf config file n n 格式字
  • 如何使用汇编获取BIOS时间?

    我正在从头开始实现一个小型操作系统 用于教育目的 现在 我想使用汇编来获取 BIOS 时间 我对此进行了很多搜索 但找不到任何代码示例来执行此操作 如果有人可以提供任何参考或代码示例或与此相关的任何内容 我将非常感激 See 时钟中断 1a
  • 在 GCC 和 Clang 下,使用 lambda 的简单 RAII 包装器的复制初始化意外失败

    我在创建一个简单的 RAII 包装器时遇到了一个意想不到的问题 更不用说下面代码的逻辑不完整性了 复制构造函数和赋值运算符未删除等 这意味着是一个SSCCE 令我印象深刻的是复制初始化我的包装器与临时 lambda 的结果会导致编译错误 而
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • C 中的模仿函数重写

    具体来说 函数重写能够调用基本重写方法 这有两部分 一个是预编译的库代码 1 另一个是库的用户代码 2 我在这里实现了一个尽可能最小的经典 Person 和 Employee 示例 非常感谢了解 OOP 概念的铁杆 C 开发人员的回应 我正
  • 线程安全的 C++ 堆栈

    我是 C 新手 正在编写一个多线程应用程序 不同的编写者将对象推入堆栈 读者将它们从堆栈中拉出 或至少将指针推入对象 C 中是否有任何内置结构可以在不添加锁定代码等的情况下处理此问题 如果没有 那么 Boost 库呢 EDIT 你好 感谢您
  • QThread - 使用槽 quit() 退出线程

    我想在线程完成运行时通知对象 但是 我无法让线程正确退出 我有以下代码 处理器 cpp thread new QThread tw new ThreadWorker connect tw SIGNAL updateStatus QStrin
  • 不要声明只读可变引用类型 - 为什么不呢?

    我一直在阅读这个问题 https stackoverflow com questions 2274412 immutable readonly reference types fxcop violation do not declare r
  • C# 中处理 SQL 死锁的模式?

    我正在用 C 编写一个访问 SQL Server 2005 数据库的应用程序 该应用程序是数据库密集型的 即使我尝试优化所有访问 设置适当的索引等 我预计迟早会遇到死锁 我知道为什么会发生数据库死锁 但我怀疑我能否在某个时候发布不发生死锁的
  • 如何不在类中实现接口的功能?

    面试时面试官问了我以下问题 但我不知道这个问题的答案是什么 请帮忙 如果我不想 我必须做什么 在我的类中实现一个函数 在接口中声明为 由我班实施 Edited 我正在使用 NET 和 C 如果有人可以提供 C 示例代码示例 那就太好了 Th
  • realloc():重新分配为 char * 上的 strcat 腾出空间时下一个大小无效 [重复]

    这个问题在这里已经有答案了 我在以下代码中收到无效内存错误 printf s n FINE 5 printf s LENGTH IS d n FINE 6 strlen buffer char realloc buffer strlen b
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 你能解释一下这个C++删除问题吗?

    我有以下代码 std string F WideString ws GetMyWideString std string ret StringUtils ConvertWideStringToUTF8 ws ret return ret W
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • 如何使用 ASP.NET Web 表单从代码隐藏中访问更新面板内的文本框、标签

    我在更新面板中定义了一些控件 它们绑定到中继器控件 我需要根据匿名字段隐藏和显示用户名和国家 地区 但问题是我无法以编程方式访问更新面板中定义的控件 我如何访问这些控件 我也在网上查找但找不到很多参考资料 下面是来自aspx页面和 cs页面
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D
  • 使用剪贴板 SetText 换行

    如何使用 SetText 方法添加换行符 I tried Clipboard SetText eee n xxxx 但当我将剪贴板数据粘贴到记事本中时 它没有给我预期的结果 预期结果 eee xxxx 我怎样才能做到这一点 Windows

随机推荐