2010-07-27 8 views
21

Je ne suis pas tout à fait sûr quand je devrais utiliser SingletonScope() vs TransientScope() vs RequestScope() quand je fais ma liaison dans mon fichier global.cs.Quand utiliser Singleton vs Transient vs Demande en utilisant Ninject et MongoDB

je par exemple mon appel à MongoSession (en utilisant NORM et le projet mvcStarter http://mvcstarter.codeplex.com/) qui est mis à SingletonScope mais je créé un référentiel qui utilise cet objet MongoSession pour faire des appels à mongo plus facile, par exemple, j'ai un NewsRepository qui utilise MongoSession pour récupérer mes éléments News à partir des données. A titre d'exemple, j'ai un appel qui récupère les articles de News dont DisplayOnHome a la valeur true et obtient la dernière version de CreationDate. Un tel référentiel devrait-il être SingletonScope ou RequestScope serait-il plus approprié?

Quand dois-je utiliser chacun d'entre eux et pourquoi?

+0

voir aussi: http: // StackOverflow!.com/questions/3338449 (Était dans ma réponse mais quelqu'un a décidé de le couper donc pas certain si c'est pertinent) –

+0

@RubenBartelink S'il vous plaît mettre à jour le lien. Elle est cassée. – shankbond

+0

@shankbond la question a été supprimée par thew quesitoner Ajout comme réponse ci-dessous –

Répondre

21

En général, dans une application Web, vous souhaitez que l'état soit l'étendue de la requête autant que possible. Uniquement dans le cas d'optimisations de très bas niveau, vous risquez probablement de rencontrer un cas où il est approprié de créer des objets singleton (et il y a des chances que vous mettiez cette logique de cache/partage dans une autre classe qui est tiré en tant que dépendance sur vos autres objets [request scope] et fait cette portée singleton). Rappelez-vous qu'un singleton dans le contexte d'une application Web signifie plusieurs threads utilisant les mêmes objets. Ce sont rarement de bonnes nouvelles. De même, la portée transitoire est la valeur par défaut la plus simple (et c'est pourquoi Ninject 2 le fait) - la portée de la requête ne doit entrer dans l'équation que si quelque chose doit être partagé pour des raisons de performances, etc. c'est simplement le contexte du partage [comme mentionné dans l'autre réponse]).

+0

Ok c'est une bonne description, donc je devrais utiliser la plupart du temps RequestScope mais pourquoi Rob utilise-t-il SingletonScope pour MongoSession dans le projet MVC Starter? – VinnyG

+0

Si 'MongoSession' est threadsafe (ce qui serait certainement le cas s'il ne maintient aucun état), singleton est correct [mais les deux autres fonctionneraient aussi]. Il est seulement nécessaire d'aller Singleton s'il y a des choses que vous voulez partager (et cela peut aider perf si la construction d'instances est chère). Garder des choses de longue durée et accéder à partir de plusieurs threads peut être bien si tous les bits 'Cela dépend' (thread sécurisé, l'état en cache n'a jamais besoin d'être sauvegardé, efficace à utiliser de plusieurs threads etc.) sont satisfaits - ce n'est pas un bon défaut. J'espère que cela clarifie quelque peu. –

+0

Qu'en est-il d'autre type d'application? – Rushino

3

Je suppose que la réponse dépend de si votre MongoSession représente ou non une unité de travail. La plupart des classes liées à la base de données avec lesquelles j'ai travaillé (principalement dans le contexte d'ORM, telles que NHibernate ou EF4) tournent autour d'un contexte, d'entités et d'états suivis représentant une unité de travail . Une unité de travail ne doit jamais être conservée plus longtemps que la durée requise pour exécuter l'unité de travail donnée, après quoi l'unité doit être validée ou annulée. Cela signifie que vous devez utiliser RequestScope.

Si votre MongoSession est pas une unité de travail, vous pouvez le garder autour pendant toute la durée d'une session MVC, auquel cas SessionScope serait alors approprié.

+0

MongoSession n'est pas une unité de travail, merci pour la réponse! – VinnyG

0

De question supprimé comme demandé par @shankbond ci-dessus


Le Dispos al est pas nécessairement effectué de manière synchrone sur votre fil de demande principale comme on pourrait le supposer.

Vous voulez probablement cacher un Block puis Dispose() il à une phase appropriée dans votre demande (comment allez-vous gérer les exceptions?)

Jetez un oeil dans les tests ninject pour plus d'exemples (au sérieux, aller LOOK - ils sont à court et clair et je na pas regretter quand j'ai écouté la 3ème fois, on m'a dit à)

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