【问题标题】:Autofac: Is it possible to pass a lifetime scope to another builder?Autofac:是否可以将生命周期范围传递给另一个构建器?
【发布时间】:2012-06-13 08:28:33
【问题描述】:

问题:

我正在用 Ui、ServiceLayer、BizLayer 和 DataLayer 构建一个四层系统。根据良好实践,ServiceLayer 对 Ui 隐藏了 BizLayer 和 DataLayer,当然 ServiceLayer 不知道 Ui 层是什么。

我的实现是一个单独的 .NET 应用程序,每一层都在自己的程序集中。我在我的 MVC3 Ui 层中使用 Autofac.MVC3 来执行 Web 请求中使用的所有解析类。我还在我的 ServiceLayer 中包含标准 Autofac,以便它可以处理我的应用程序中所有其他层的注册。在系统启动时,我调用一个方法来向 Autofac 注册所有类型。这样做:

  1. 通过调用 ServiceLayer 中的模块来注册较低级别。它使用标准 NuGet Autofac 包处理自身和所有其他程序集的注册。
  2. 然后Ui层使用NuGet Autofac.MVC包注册各种控制器和IActionInvoker进行Action Method注入。

我的 DataLayer 中的 UnitOfWork 类当前已在 InstancePerLifetimeScope 中注册,因为它是由使用普通 Autofac 的 ServiceLayer 注册的,并且对 InstancePerHttpRequest 一无所知。但是我读到 here 我应该使用 InstancePerHttpRequest 范围。

问题:

我的问题是,我可以传递一个生命周期范围,即 MVC 层可以将 InstancePerHttpRequest 传递给服务层以在需要的地方使用吗? Alex Meyer-Gleaves 在下面的post 的评论中似乎暗示这是可能的:

也可以将您自己的 ILifetimeScopeProvider 实现传递给 AutofacDependencyResolver,以便您可以控制在 ASP.NET 运行时之外的生命周期范围的创建

但是,他建议的方式似乎是 MVC 特定的,因为 ILifetimeScopeProvider 是 MVC 扩展类。任何人都可以提出另一种方式或者 InstancePerLifetimeScope 可以吗?

【问题讨论】:

  • 你的图层有多分离? “服务层”是一个单独的应用程序还是所有这些东西都在同一个应用程序/AppDomain 中? (如果它们被 AppDomain 分开,您将很难通过任何东西。)您目前如何解决应用程序中的问题?您通常需要传递生命周期范围的唯一原因是如果您正在执行服务定位,这在某种程度上是一种反模式。

标签: oop autofac


【解决方案1】:

InstancePerHttpRequestScope 实际上是 InstantPerLifetimeScope 的一个变体。第一个仅适用于请求。如果你想在后台线程上执行一些东西,它将不可用。

和你一样,我在 as.net mvc 和多个应用层中使用 autofac。对于需要拥有生命周期范围的情况,我会绕过 Container 本身。我有一个执行任务的后台队列。每个任务几乎都需要有自己的范围并在事务中执行。 Queue 有一个 IContainer 实例(它是一个单例),对于每个任务,它都会开始一个新的范围并执行该任务。

为了在这种情况下工作,Db 访问和所有设置都设置为 INstancePerLifetimeScope,我在控制器中使用它们时没有问题。

【讨论】:

  • 感谢 Mike 的 cmets。在这种情况下,我正在考虑对持久层 UnitOfWork 的调用是 HTTPRequest 的一部分,例如类似于用户输入写入数据库的数据。看起来 InstancePerLifetimeScope 可以工作(尽管我仍处于单元测试模式,所以还不确定),但我在问题中提到的 Travis Illig 帖子确实声明您应该使用 InstancePerHttpRequest。我只是想看看是否有办法将 InstancePerHttpRequest 生命周期范围向下传递到较低层以供使用。
  • 我不同意你必须使用它的事实。如果你想在 http 请求之外使用同一个容器,它是行不通的。您不能传递 InstancePerHttpRequest,因为范围包含在请求中执行的所有内容,包括数据库内容。如果您确定不会在请求之外使用 Container,则可以毫无问题地使用 InstancePerHttpRequest。
  • 谢谢 MikeSW,我认为你是对的。我被指出了一个帖子here,我读到它说 InstancePerLifetimeScope 是“在 MVC 的情况下,这始终是特殊的 HTTP 请求生命周期范围。”。我会同意的。
【解决方案2】:

在 MikeSW、Cecil Philips 和 Travis Illig(谢谢大家)的帮助下,我走上了正轨。我阅读了各种帖子,尤其是 Alex Meyer-Gleaves 帖子here,似乎 InstancePerLifetimeScope 在由 Autofac.MVC 包解决时被视为 InstancePerHttpRequest,在某些限制内(请阅读 Alex 的帖子了解这些限制)。亚历克斯的评论是:

使用 InstancePerHttpRequest 可确保在运行时从正确的生命周期范围解析服务。在 MVC 的情况下,这始终是特殊的 HTTP 请求生命周期范围。

这意味着我可以安全地将整个 htpp 请求需要单个实例的任何内容注册为 InstancePerLifetimeScope,只要我没有子范围的项目,它就可以正常工作。这很好,我可以使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    相关资源
    最近更新 更多