Ninject:是否可以在SingletonScope中使用父对象,在TransientScope中使用子对象?
几个星期以来,我一直在用这种方式绞尽脑汁……我现在拥有的是这样的:
- 一堆
*Service
类 - 所有这些都依赖于通过EF访问数据库的不同
*Repository
类 - 为了允许unit testing,将
DbContext
注入到存储库中。 (所以我不能用于处理上下文)
要正确处理注入的EF上下文,我可以在InRequestScope()
或简单的自定义作用域中运行我的依赖树 – InScope(c => new object())
和所有其他级别的InParentScope()
。
这两种方法都会在每个请求期间创建和处理大量对象。 另外我们讨论的是单页应用程序,因此95%的查询(大约50个)将在2个请求中执行,因此InRequestScope()
似乎不是一个好主意。 此外, *Service
类不保持状态,因此可以是InSingletonScope()
并且可以最小化对象创建量。
问题
是否有可能在InSingletonScope()
拥有parent *Service
和*Repository
类,并以某种方式将EF DbContext
注入到每次访问时将返回一个新实例的范围,并使用NInject来表示IDisposable
?
我知道在创建对象时会注入依赖项,但这仍然可以通过某种方式进行管理吗?
不,这是不可能的。 如果你考虑一下,你应该明白为什么。
单个对象将在应用程序的生命周期中存在。 InRequestScope对象在请求的生命周期中存在。 由于您的单例存储库将永久存在,并且它将保存对DbContext的引用(因为它是依赖项),这意味着如果没有您的存储库具有某种释放机制,则无法对dbcontext进行垃圾收集。
即使您确实提供了这样的机制,您也必须有另一种机制来在下一个请求中重新获取新实例,因为不会创建新的单例存储库(因此它的构造函数将不会被调用,因此它的依赖关系将无法解析,因此它无法了解新的dbcontext)。
因此,实际上,使InRequestScope对象成为单个对象的依赖关系将有效地使InRequestScope对象成为单例,否则该对象将从单例下面处理掉,这可能是坏事。
另外,我不同意你的事实是你的存储库有状态。 状态是DbContext本身。 由于Singleton是一个应用程序范围的静态实例,因此您可以为使用您的应用程序的所有用户提供相同的实例,这意味着它也会提供相同的DbContext,这是一个巨大的禁忌,因为您的用户会踩到彼此DbContext状态。
同样,您的服务也是有状态的,因为它们具有存储库,正如我刚才指出的那样,DbContexts是有状态的。
你想要做的只是简单地使你的服务,存储库和DbContexts都是InRequestScope。
我不明白为什么这种方法会“在每个请求期间创建大量对象”。 重点是它只为每个请求创建每个对象类型的一个实例。