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