When to use Singleton vs Transient vs Request using Ninject and MongoDB
Asked Answered
B

3

22

I'm not quite sure when I should use SingletonScope() vs TransientScope() vs RequestScope() when I do my binding in my global.cs file.

I have for example my call to MongoSession (using NoRM and the mvcStarter project http://mvcstarter.codeplex.com/) which is set to SingletonScope but I created a repository that use this MongoSession object to make calls to Mongo easier, e.g., I have a NewsRepository which uses MongoSession to fetch my News items from the data. As an example I have a call that fetches News items that has DisplayOnHome set to true and get the latest by CreationDate. Should such a repository be SingletonScope or would RequestScope would be more appropriate?

When should I use each of it and why?

Biffin answered 27/7, 2010 at 21:21 Comment(3)
see also: stackoverflow.com/questions/3338449 (Was in my answer but someone decided to chop it out so not certain if its relevant)Thuggee
@RubenBartelink Please update the link. It is broken.Piggott
@shankbond the question got deleted by thew quesitoner Adding as answer belowThuggee
T
21

In general in a web app, you want state to be request scope as much as possible.

Only in the case of very low level optimisations are you ever likely to run into a case where its appropriate to create singleton objects (and the chances even then are that you'll pull such caching / sharing logic out into another class which gets pulled in as a dependency on your other [request scope] objects and make that singleton scope). Remember that a singleton in the context of a web app means multiple threads using the same objects. This is rarely good news.

On the same basis, transient scope is the most straightforward default (and that's why Ninject 2 makes it so) - request scope should only come into the equation when something needs to be shared for performance reasons, etc. (or because that's simply the context of the sharing [as mentioned in the other answer]).

Thuggee answered 27/7, 2010 at 21:41 Comment(4)
Ok that's a good description, so I should use most of the time RequestScope but why does Rob use SingletonScope for the MongoSession in the MVC Starter project?Biffin
If MongoSession is threadsafe (which would definitely be the case if it doesnt maintain any state whatsoever), singleton is fine [but the other two would work too]. It's only necessary to go Singleton if there is stuff you want to share (and it may help perf if constructing instances is expensive). Keeping stuff long lived and accessing it from multiple threads may be fine if all the 'It Depends' bits (thread safe, cached state never needs to be dumped, efficient to use from multiple threads etc.) are satisfied - it's just not a good default. Hope this clarifies somewhat.Thuggee
What about other kind of app ?Ketch
@Ketch That's way too open-ended -- you haven't asked anything... Perhaps you could ask a question in which you explain what sort of an app you are doing, and which objects need to be long lived vs short term. e.g. do you maintain sessions against a particular server but also offer an option to disconnect and then connect to another one etc.Thuggee
P
3

I guess the answer would depend on whether your MongoSession represents a unit of work or not. Most database related classes that I've worked with (mostly in the context of ORM, such as NHibernate or EF4) revolve around a context, entities, and tracked state that represent a unit of work. A unit of work should never be kept around longer than the length of time required to perform the given unit of work, after which the unit should be committed or rolled back. That would mean you should use RequestScope.

If your MongoSession is not a unit of work, you could keep it around for the lifetime of an MVC session, in which case SessionScope would then be appropriate.

Photofinishing answered 27/7, 2010 at 21:40 Comment(0)
T
0

From deleted question as requested by @shankbond above


The Disposal is not necessarily performed synchronously on your main request thread as one might assume.

You probably want to stash a Block and then Dispose() it at an appropriate phase in your request (how are you going to handle exceptions?)

Have a look in the Ninject Tests for more examples (seriously, go look - they're short and clear and I didnt regret it when I listened the 3rd time I was told to!)

See http://kohari.org/2009/03/06/cache-and-collect-lifecycle-management-in-ninject-20/

Thuggee answered 10/11, 2016 at 19:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.