Asp.net mvc 3 Autofac-混合InstancePerHttpRequest和异步作用域

Asp.net mvc 3 Autofac-混合InstancePerHttpRequest和异步作用域,asp.net-mvc-3,scope,autofac,Asp.net Mvc 3,Scope,Autofac,我正在构建一个以MVC3为主前端的四层系统,其中包含由服务层异步运行的长时间运行的任务,并报告进度,MVV将使用Ajax显示这些任务。我使用Autofac进行依赖注入(DI),主要是因为接口和文档很好,而且速度很快(请参阅Philip Mateescu关于的这篇优秀研究) 我的问题是如何设置Autofac来处理注入项的两个作用域,即MVC3依赖项必须是PerHttpRequest,但异步任务依赖项必须是InstancePerLifetimeScope 显然,服务层需要使用单独的DI来解决长期运行

我正在构建一个以MVC3为主前端的四层系统,其中包含由服务层异步运行的长时间运行的任务,并报告进度,MVV将使用Ajax显示这些任务。我使用Autofac进行依赖注入(DI),主要是因为接口和文档很好,而且速度很快(请参阅Philip Mateescu关于的这篇优秀研究)

我的问题是如何设置Autofac来处理注入项的两个作用域,即MVC3依赖项必须是PerHttpRequest,但异步任务依赖项必须是InstancePerLifetimeScope

显然,服务层需要使用单独的DI来解决长期运行任务的依赖关系。这样做的最佳方式是什么?

更新-2014年6月 随着使用AutoFac的最佳实践的发展,以及MVC的变化,我更新了这个答案。变化在于,AutoFac中的最佳实践现在是使用.InstancePerLifetimeScope()后缀定义需要在整个访问生命周期内持续的任何实例(对于MVC-HttpRequest)。请参见下面的示例:

builder.RegisterType<MyDbContext>().As<IMyDbContext>().InstancePerLifetimeScope();
builder.RegisterType();
完成此操作后,您不再需要指定在任务中创建的新生存期范围的名称(请参见下面已更新的原始答案)

下面是一些关于MVC中任务分配的其他注意事项,您可能会发现这些注意事项很有用:

  • 如果您使用的是新的async/await,则不需要新的生存期范围。Aysnc/await保留当前上下文,并简单地释放线程以提高负载下web的性能
  • 如果你真的想在后台运行一些东西,那么你会被警告——这有一些问题。我建议您阅读异步专家Stephen Cleary的文章
  • 一个非常有用的组合是将signar与MVC结合使用来报告进度并允许用户取消。这对我很有效

原始帖子,但已更新(注意:您必须如上所示注册生存期范围实例)

我发现了如何通过GoogleAutofac组处理具有依赖项的异步任务。事实证明,您可以访问MVC级别的容器,然后创建解析的新生存期范围。有很多方法可以做到这一点,但亚历克斯·迈耶·格里夫斯(Alex Meyer Gleaves,专家)的这篇文章提供了答案。Alex建议使用以下代码来运行具有不同作用域的任务

public void Run<T>(Action<T> action)
{
  Task.Factory.StartNew(delegate
  {
    using (var container = AutofacDependencyResolver.Current
                           .ApplicationContainer.BeginLifetimeScope())
    {
        var service = container.Resolve<T>();
        action(service);
    }
  });
}
公共作废运行(操作)
{
Task.Factory.StartNew(委托
{
使用(var container=autofacdependencysolver.Current
.ApplicationContainer.BeginLifetimeScope())
{
var service=container.Resolve();
行动(服务);
}
});
}

Alex的帖子中有一个关于这个主题的更详细的博客帖子链接,这也是非常有用的。

我不确定你问题的第二部分是否很清楚。你能提供一些代码片段或补充说明吗?嗨,特拉维斯,谢谢你看这个,对不起,第二个问题有点模糊。我在其他地方找到了更多的信息,因此删除了我的第二个问题,因为它有点太复杂,无法在几行中列出。我保留了原始信息,因为它可能对其他人有用。谢谢。请在此处添加答案作为答案,而不是编辑您的问题。这是堆栈溢出问答格式的最佳方式。谢谢,谢谢你的邀请,乔恩·史密斯。你手头不会有一个关于InstancePerLifetimeScope最佳实践与MVC+Autofac的链接吧?我看了看,但没有喜悦…嗨,约翰尼·赖利。它在wiki中的控制范围和生存期->实例范围下。希望有帮助。