Ninject:是否可以在 SingletonScope 中拥有父对象,在 TransientScope 中拥有子对象? [英] Ninject: Is it possible to have parent object in SingletonScope and child in TransientScope?

查看:21
本文介绍了Ninject:是否可以在 SingletonScope 中拥有父对象,在 TransientScope 中拥有子对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have been racking my brain on and off with this for a few weeks now... What I currenlty have is this:

  • 一堆*Service
  • 所有这些都依赖于通过 EF 访问数据库的不同 *Repository
  • 为了允许单元测试,将 DbContext 的派生类注入到存储库中.(所以我不能使用 using 来处理上下文)
  • A bunch of *Service classes
  • All of these depend on different *Repository classes that access database via EF
  • To allow Unit Testing a derivate of DbContext is injected into repositories. (so I can not use using to dispose of the contexts)

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

To correctly dispose of the EF contexts that are injected I could run my dependency tree in InRequestScope() or in a simple custom scope - InScope(c => new object()) on the top level and in InParentScope() on all other levels.

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

Both of these approaches would create and dispose a lot of objects during each request. In addition we are talking about a single page application so that 95% of the queries (50 or so) will be executed during 2 requests so InRequestScope() seems not to be a good idea. Also the *Service classes hold no state and thus could be InSingletonScope() and would minimize the amount of object creation.

问题

是否有可能在 InSingletonScope() 中有父 *Service*Repository 类并以某种方式注入 EF DbContext 在每次访问时都会返回一个新实例的范围内,并且会使用 NInject 来支持 IDisposable?

Is it possible to have parent *Service and *Repository classes in InSingletonScope() and somehow inject EF DbContext in a scope that will return a new instance each time it is accessed and will honor IDisposable using NInject?

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

I know that dependencies are injected while objects are created but could this still be somehow managed?

推荐答案

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

No, it's not possible. If you think about it, you should understand why.

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

A singleton object will exist for the lifetime of the application. An InRequestScope object lives for the lifetime of a request. Since your singleton repository will live forever, and it will hold a reference to your DbContext (because it's a dependency), that means the dbcontext cannot be garbage collected without your repository having some mechanism to release it.

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

Even if you did supply such a mechanism, you'd have to have another mechanism to re-acquire a new instance on the next request, because a new singleton repository will not be created (and thus it's constructor will not be called, and thus it's dependencies will not be resolved, and thus it will not be able know about the new dbcontext).

因此,实际上,使 InRequestScope 对象成为单例对象的依赖项将有效地使 InRequestScope 对象成为单例,否则该对象将从单例下被处理掉,这可能很糟糕.

So, in effect, making an InRequestScope object a dependency of a singleton object would effectively make the InRequestScope object a singleton, or else the object will be disposed out from under the singleton and that could be bad..

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

Also, I beg to differ with you on the fact that your repositories DO have state. The state is the DbContext itself. Since a Singleton is an application wide static instance, you give the same instance to all users using your app, which would mean it would also give the same DbContext, which is a huge no-no, since your users would stomp all over each others DbContext state.

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

Your services are also, likewise, stateful because they have repositories, which as I've just pointed out have DbContexts, which are stateful.

您要做的只是让您的服务、存储库和 DbContext 都在 InRequestScope 中.

What you want to do is simply make your Services, repositories, and DbContexts all InRequestScope.

我不明白为什么这种方法会在每个请求期间创建大量对象".重点是它只为每个请求创建每个对象类型的一个实例.

I fail to understand why this approach would "create lots of objects during each request". The whole point is that it only creates one instance of each object type per request.

这篇关于Ninject:是否可以在 SingletonScope 中拥有父对象,在 TransientScope 中拥有子对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆