【问题标题】:Why does Microsoft warn from using PerRequestLifetimeManager为什么微软会警告使用 PerRequestLifetimeManager
【发布时间】:2016-07-18 14:30:58
【问题描述】:

https://msdn.microsoft.com/en-us/library/microsoft.practices.unity.perrequestlifetimemanager(v=pandp.30).aspx 声明:

虽然 PerRequestLifetimeManager 生命周期管理器可以正常工作,并且可以帮助处理 HTTP 请求范围内的 有状态 或线程不安全的依赖项,但在可能的情况下使用它通常不是一个好主意应避免,因为如果使用不当,通常会导致不良做法或难以在最终用户的应用程序代码中发现错误。建议您注册的依赖项是无状态的,如果在 HTTP 请求的生命周期内需要在多个对象之间共享公共状态,那么您可以拥有一个无状态服务,使用 Items 集合显式存储和检索此状态当前对象。

警告指的是哪种错误或不良做法?怎么会不正确地使用它? - 不幸的是,警告不是很具体,因此很难应用于现实世界。此外,我不清楚在这种情况下有状态意味着什么。

恕我直言,使用 PerRequestLifetimeManager 的典型场景是某种数据库连接(例如 DbContext)或类似的。

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework unity-container


    【解决方案1】:

    其目的是为每个请求仅实例化一个实例,这可以(例如)防止在单个请求过程中的冗余操作和查找。

    危险在于如果有人认为创建的对象是在请求期间存储状态的好地方。依赖注入的想法是一个类接收一个依赖项(通常是一个接口),并且除了实现该接口之外,根本不“知道”任何关于它的东西。

    但有人可能会认为,如果对象将在请求的整个生命周期中持续存在,那么它是在请求期间保持状态的好地方。因此,他们创建了一个复杂的场景,其中一个类接收依赖项,在其中存储一些信息(例如设置属性),然后另一个类接收相同的依赖项并期望读取该属性。

    现在依赖注入(解耦)的目的已经失败,因为类有关于该依赖的生命周期的内置假设,甚至可能包括关于其他类已经完成或将要对其状态做什么的假设目的。这造成了一个复杂的混乱,其中类之间的交互很难感知——甚至是隐藏的——因此很容易被打破。

    假设有人确定该依赖项的生活方式应该是暂时的,而不是每个网络请求。突然间,依赖它的类的所有行为都按预期停止工作。所以开发人员查看这些类,发现没有任何改变。发生了什么?这些类之间的交互一开始就很难看到,所以当它中断时,将很难找到问题。如果有一些正当的理由可以改变这种依赖的生活方式,那么问题将更难解决。

    如果我们需要在请求期间存储状态,那么我们应该把它放在“正常”的地方,比如HttpContext。仍然存在一些令人困惑的做法和错误的空间,但至少我们知道HttpContext(根据定义)将与特定请求相关联。

    【讨论】:

      猜你喜欢
      • 2011-01-16
      • 2014-09-25
      • 2010-12-07
      • 1970-01-01
      • 2020-08-26
      • 1970-01-01
      • 2019-05-27
      • 2012-02-24
      • 2016-04-06
      相关资源
      最近更新 更多