更新 - 2014 年 6 月
我已经更新了这个答案,因为使用 AutoFac 的最佳实践已经继续,加上 MVC 的变化。变化在于,AutoFac 中的最佳实践现在是通过使用 .InstancePerLifetimeScope() 后缀来定义需要在访问的整个生命周期内持续的任何实例,在 MVC 的 HttpRequest 的情况下。请参阅下面的示例:
builder.RegisterType<MyDbContext>().As<IMyDbContext>().InstancePerLifetimeScope();
完成此操作后,您不再需要指定您在任务中创建的新生命周期范围的名称(请参阅下面已更新的原始答案)。
以下是有关 MVC 中任务分配的其他一些说明,您可能会发现它们很有用:
- 如果您使用的是新的 async/await,则不需要新的生命周期范围。Aysnc/await 保留当前上下文并简单地释放线程以提高 Web 在负载下的性能。
- 如果您确实想在后台运行某些东西,那么请注意 - 存在一些问题。我建议您阅读异步专家 Stephen Cleary 的这篇有用的博客文章。
- 一个真正有用的组合是将 SignalR 与 MVC 结合使用来报告进度并允许用户取消。这对我来说效果很好。
原始帖子,但已更新(注意:您必须如上所示注册生命周期范围实例)
我已经通过 Google Autofac 组找到了如何处理具有依赖关系的异步任务。事实证明,您可以访问 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);
}
});
}
在 Alex 的帖子中有一个关于该主题的更详细博客帖子的链接,这也非常有用。