3

几个星期以来,我一直在为此绞尽脑汁……我现在拥有的是:

  • 一堆*Service
  • 所有这些都依赖于*Repository通过 EF 访问数据库的不同类
  • 为了允许单元测试的派生DbContext被注入到存储库中。(所以我不能using用来处理上下文)

为了正确处理注入的 EF 上下文,我可以InRequestScope()在一个简单的自定义范围内或在一个简单的自定义范围内运行我的依赖树 -InScope(c => new object())在顶层和InParentScope()所有其他级别上。

这两种方法都会在每个请求期间创建和处置大量对象。此外,我们谈论的是单页应用程序,因此 95% 的查询(大约 50 个)将在 2 个请求期间执行,因此InRequestScope()似乎不是一个好主意。此外,这些*Service类没有状态,因此可以InSingletonScope()并且将最小化对象创建的数量。

问题

是否可以在其中包含父类*Service*RepositoryInSingletonScope()并以某种方式将 EF 注入DbContext一个范围内,该范围将在每次访问时返回一个新实例并IDisposable使用 NInject 兑现?

我知道在创建对象时注入了依赖项,但这仍然可以以某种方式管理吗?

4

1 回答 1

4

不,这是不可能的。如果你仔细想想,你应该明白为什么。

单例对象将在应用程序的整个生命周期中存在。InRequestScope 对象在请求的整个生命周期内都存在。由于您的单例存储库将永远存在,并且它将保存对您的 DbContext 的引用(因为它是一个依赖项),这意味着如果您的存储库没有某种机制来释放 dbcontext,则无法对 dbcontext 进行垃圾收集。

即使您确实提供了这样的机制,您也必须有另一种机制来在下一次请求时重新获取新实例,因为不会创建新的单例存储库(因此不会调用它的构造函数,因此它的依赖关系不会被解析,因此它无法知道新的 dbcontext)。

因此,实际上,使 InRequestScope 对象成为单例对象的依赖项将有效地使 InRequestScope 对象成为单例对象,否则该对象将从单例对象下释放出来,这可能会很糟糕。

另外,我请求与您不同的是,您的存储库确实状态。状态是 DbContext 本身。由于 Singleton 是应用程序范围内的静态实例,因此您为使用您的应用程序的所有用户提供相同的实例,这意味着它也会提供相同的 DbContext,这是一个巨大的禁忌,因为您的用户会互相踩踏DbContext 状态。

同样,您的服务也是有状态的,因为它们具有存储库,正如我刚刚指出的那样,它们具有有状态的 DbContexts。

您要做的只是让您的服务、存储库和 DbContexts 都成为 InRequestScope。

我不明白为什么这种方法会“在每个请求期间创建大量对象”。关键是它只为每个请求创建每个对象类型的一个实例。

于 2013-08-13T08:50:24.743 回答