管理每个会话和请求AutoFac寿命范围在asp.net MVC 3(Managing AutoFa

2019-06-26 15:24发布

我想在一个Web应用程序使用AutoFac。 我有根容器,每节子容器和每个请求的子容器。 我试图找出/ A最好的办法就是管理这些寿命范围是什么。 在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
  • 身份验证和授权范围内(例如,用户身份和角色)

不相关的,我要建立的应用程序,但在电子商务环境下,购物车可能是会话范围。 这可能是最好的具体例子。 这是你的预期寿命长于要求的东西,但短于应用程序。

可能有比这更多,但如果我对使用UserPreferences,认证和授权的策略,则该策略也被应用到后面将要创建的其他组件。

另一种可能是在请求开始获得所有必要的信息,并在请求范围内将这些配置的组件。 它将给我结果我期待,但它并没有对应用程序 - >会话级>请求层次我的模型在我的脑海匹配。 我希望创建一个系统,是有道理的,因为我绝对不会说是要保持它的人。

Answer 1:

什么你需要做的是实现自己的Autofac.Integration.Mvc.ILifetimeScopeProvider 。 这个接口是什么支配如何/在哪里获取生成请求寿命范围。 默认的, Autofac.Integration.Mvc.RequestLifetimeScopeProvider ,把手上的每个请求的基础上创建,处理和寿命范围的维修。

你可以浏览代码RequestLifetimeScopeProvider在这里 ,我强烈建议做的,如果你打算从事这个。 这是我能想到包含显示的这些东西一个有责任的工作代码的最佳样本。

你的实现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 ,该会议将不会被再水化(无论是在进程内或没有)。 Web表单和MvcHandler实现,默认情况下,所以你不会看到任何问题,但如果你有需要注射自定义处理程序,你会打一些碰壁,因为“会话”不会对这些请求存在。
  4. Session_End中并不总是闪光 。 每对SessionStateModule.End的文档 ,如果你使用外的进程内会话状态,你不会真正得到Session_End中的事件,所以你将无法收拾。

鉴于限制,一般的好,尽量远离会话存储的范围之遥。 但是......如果这就是你要做什么,该ILifetimeScopeProvider是做它的方式。



文章来源: Managing AutoFac lifetime scopes per session and request in asp.net mvc 3