Ninject: Is it possible to have parent object in SingletonScope and child in TransientScope?

懵懂的女人 提交于 2019-12-06 07:32:32

问题


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

  • 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)

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.

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.

The Question

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?


回答1:


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

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.

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).

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..

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.

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

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.



来源:https://stackoverflow.com/questions/18203401/ninject-is-it-possible-to-have-parent-object-in-singletonscope-and-child-in-tra

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!