[英]Managing AutoFac lifetime scopes per session and request in asp.net mvc 3
我想在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();
}
如何告诉AutoFac使用我的requestScope作为获取依赖项的起点,以便我使用requestScope解析我注册为InstancePerLifetimeScope的实现?
如果那是不可能的,我可以让AutoFac从我的sessionScope中创建每个请求的生命周期范围吗?
或者我在这里走错了路? 可以有另一种方法让AutoFac知道这种层次结构吗?
任何帮助或其他意见表示赞赏。
回应史蒂文。
我还处于原型设计的早期阶段,但是你可以在sessionScope中找到可能的东西:
与我要构建的应用程序无关,但在电子商务环境中,购物车可以是会话范围的。 这可能是最好的具体例子。 您希望它比请求更长寿,但比应用程序更短。
可能有更多,但如果我有UserPreferences,身份验证和授权的策略,那么该策略也可以应用于稍后将创建的其他组件。
可能的替代方法是在请求开始时获取所有必要信息,并将这些已配置的组件放在请求范围中。 它会给我我期望的结果,但它与我在脑海中关于application-> session-> request hierarchy的模型不符。 我希望创建一个有意义的系统,因为我绝对不是那个要维护它的系统。
您需要做的是实现自己的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);
关于会话级范围概念的几句警告:
[Serializable]
...即使它是,生活在那里的已解析对象也不一定都标记为可序列化。 这很重要,因为这意味着会话级生命周期范围可能适用于具有内存中会话的单个框,但如果您使用SQL会话或会话服务部署到服务器场,则会因为会话无法序列化而崩溃你存储的范围。 如果您选择不对作用域进行序列化,那么跨机器的每个用户都有不同的作用域 - 这也是一个潜在的问题。 鉴于这些限制,尝试远离会话存储的范围通常是好的。 但是......如果这就是你要做的事情,那么ILifetimeScopeProvider
就是这样做的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.