gpt4 book ai didi

c# - 在 asp.net mvc 3 中管理每个 session 和请求的 AutoFac 生命周期范围

转载 作者:太空狗 更新时间:2023-10-29 22:16:40 28 4
gpt4 key购买 nike

我想在网络应用程序中使用 AutoFac。我有根容器,每个 session 有一个子容器,每个请求有一个子容器。我试图弄清楚管理这些生命周期范围的最佳方法是什么。在 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 了解此层次结构?

如有任何帮助或其他意见,我们将不胜感激。


回应史蒂文。

我仍处于原型(prototype)制作的早期阶段,但您可能在 sessionScope 中拥有的东西:

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

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

可能不止于此,但如果我有 UserPreferences、Authentication 和 Authorization 的策略,那么该策略也可以应用于稍后创建的其他组件。

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

最佳答案

您需要做的是实现您自己的 Autofac.Integration.Mvc.ILifetimeScopeProvider。该接口(interface)控制如何/在何处生成请求生命周期范围。默认的 Autofac.Integration.Mvc.RequestLifetimeScopeProvider 处理基于每个请求的生命周期范围的创建、处置和维护。

You can browse the code for RequestLifetimeScopeProvider here ,如果您打算这样做,我强烈建议您这样做。这是我能想到的最好的示例,其中包含显示其中一个事物的责任的工作代码。

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

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

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

关于 session 级范围概念的几句警告:

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

鉴于这些限制,通常最好尽量远离 session 存储范围。但是...如果这就是您要执行的操作,ILifetimeScopeProvider 就是执行此操作的方法。

关于c# - 在 asp.net mvc 3 中管理每个 session 和请求的 AutoFac 生命周期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11721919/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com