我正在构建一个以MVC3为主要前端的四层系统,但包含由服务层异步运行并报告进度的长期运行任务,MVV将使用Ajax显示。我使用Autofac进行依赖注入(DI)主要是因为接口和文档很好而且速度快(参见Philip Mateescu在DI speed上的这篇优秀研究)。
我的问题是如何设置Autofac来处理注入项的两个范围,即MVC3依赖项必须是PerHttpRequest,但异步任务依赖项必须是InstancePerLifetimeScope。
显然,服务层需要使用单独的DI来解决长时间运行的任务的依赖关系。这样做的最佳方式是什么?
答案 0 :(得分:7)
我已经更新了这个答案,因为使用AutoFac的最佳做法已经开始,加上MVC的变化。更改是AutoFac的最佳实践现在是通过使用.InstancePerLifetimeScope()后缀来定义在MVC HttpRequest的情况下需要持续访问整个生命周期的任何实例。请参阅下面的示例:
builder.RegisterType<MyDbContext>().As<IMyDbContext>().InstancePerLifetimeScope();
完成后,您不再需要在任务中指定要创建的新生命周期范围的名称(请参阅下面的原始答案,已更新)。
以下是一些关于MVC任务的其他注意事项,您可能会发现它们很有用:
原帖,但已更新(注意:您必须注册生命范围实例,如上所示)
我已经找到了如何通过Google Autofac组处理具有依赖关系的异步任务。事实证明,您可以访问MVC级别容器,然后创建解决方案的新生命周期范围。有很多方法可以做到这一点,但是Alex Meyer-Gleaves(他是专家)的这个answer提供了答案。 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的帖子中有关于该主题的更详细的博客文章here的链接,这也非常有用。