2010-05-09 8 views
0

La classe Repository a un comportement singleton et _db implémente le modèle jetable. À l'exception de l'objet _db est disposé après le premier appel et en raison du comportement de singleton tout autre appel de _db se bloque.Question de définition de classe (Comportement jetable et singleton)

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] 
public class Repository : IRepository 
{ 
    private readonly DataBase _db; 

    public Repository(DataBase db) 
    { 
     _db = db; 
    } 

    public int GetCount() 
    { 
     using(_db) 
     { 
      return _db.Menus.Count(); 
     } 
    } 

    public Item GetItem(int id) 
    { 
     using(_db) 
     { 
      return _db.Menus.FirstOrDefault(x=>x.Id == id); 
     } 
    } 

    } 

Ma question est, est-il possible de concevoir cette classe pour fonctionner correctement sans enlever le comportement singleton? La classe Repository servira une grande quantité de demandes.

Répondre

2

Lorsque vous fournissez une instance DataBase au Repository, cela signifie la création et l'élimination est pas dans le cadre de la classe Repository. Par conséquent, Repository ne doit pas disposer de cette instance. Vous devez supprimer les instructions using et tout ira bien. Écrivez le Repository comme suit:

public class Repository : IRepository 
{ 
    private readonly DataBase _db; 

    public Repository(DataBase db) 
    { 
     _db = db; 
    } 

    public int GetCount() 
    { 
     return _db.Menus.Count(); 
    } 

    public Item GetItem(int id) 
    { 
     return _db.Menus.FirstOrDefault(x=>x.Id == id); 
    } 
} 
+0

Comme les actes de classe comme référentiel un singleton, en gardant un contexte à long en cours d'exécution est une mauvaise pratique. Il peut se développer très rapidement dans la consommation de mémoire. – user137348

+1

Je suis d'accord que garder le contexte pendant longtemps est une mauvaise pratique. Dans ce cas, vous avez deux options. 1. N'utilisez pas le 'Repository' comme singleton et renvoyez une nouvelle instance sur chaque requête. 2. Passez la classe 'DataBase' à chaque appel de la méthode. Je voudrais aller à l'option 1. N'oubliez pas que, à côté du problème de disposer, vous devez vous assurer que votre 'DataBase' est thread-safe lorsque vous retournez le' Repository' comme un singleton (quand vous êtes dans un multi environnement fileté). – Steven

+1

si garder un contexte de longue durée est une mauvaise pratique, pourquoi est-ce un singleton? – Vitalik

2

Lorsque vous faites ceci:

using(_db) 

vous garantissez Cédant() sera appelé sur votre objet.

Je suggère de changer cela pour utiliser une classe statique avec un membre statique privé pour _db.

public static class Repository { 
    private static DataBase _db; 

    // static constructor 
    static Repository() { 
    _db = new Database(); 
    } 

    public static int GetCount() { 
    return _db.Menus.Count(); 
    } 
    public Item GetItem(int id) { 
    return _db.Menus.FirstOrDefault(x=>x.Id == id); 
    } 
}