为什么Microsoft会因使用PerRequestLifetimeManager

时间:2016-07-18 14:30:58

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

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

  

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

警告提到了什么样的错误或不良做法?怎么会错误地使用它? - 不幸的是,警告不是很具体,因此很难适用于现实世界。此外,我不清楚在这种情况下有什么有状态的手段。

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

1 个答案:

答案 0 :(得分:4)

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

如果有人认为在请求期间创建的对象是存储状态的好地方,则存在危险。依赖注入的想法是类接收依赖(通常是接口)并且不知道"知道"关于它的任何事情,除了它实现了该接口。

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

现在依赖注入(解耦)的目的已经失败,因为类具有关于该依赖的生命周期的内置假设,甚至可能包括关于其他类已经完成或将要对其状态做什么的假设宾语。这造成了混乱的混乱,在这种混乱中,类之间的相互作用很难被察觉 - 甚至是隐藏的 - 因此它很容易被打破。

让我们说某人确定该依赖的生活方式应该是暂时的,而不是每个网络请求。突然之间,依赖它的那些类的所有行为都停止了预期的工作。因此开发人员会查看这些类,并发现没有任何变化。发生了什么?这些类之间的相互作用很难在一开始就很难看到,所以当它破裂时,很难找到问题。如果有一些有效的理由说明为什么这种依赖的生活方式发生了变化,那么这个问题将更加难以解决。

如果我们需要在请求期间存储状态,那么我们应该将其放入" normal" HttpContext中的地方。在那里仍有一些令人困惑的做法和错误的空间,但至少我们知道HttpContext(根据定义)将与特定请求相关联。