2010-10-02 3 views
0

Je cherche à obtenir des commentaires sur la façon dont je peux améliorer mon design. Plus précisément, je ne veux pas avoir à créer un nouvel objet de référentiel pour chacun de mes objets de domaine, mais je ne veux pas non plus réécrire la logique de session et de transaction à plusieurs reprises.Nhibernate Architecture - Référentiel Nhibernate générique pour servir de nombreux types différents

Pour atténuer le besoin d'écrire le code pour obtenir une nouvelle session et transation pour chaque transaction de base de données que je fais que j'ai créé et classe abstraite générique qui ressemble à ceci:

public class AbstractNHibernate<T> where T : class 
{ 

    public void Add<T>(T entity) 
    { 
     using(ISession session = NHibernateHelper.OpenSession()) 
     using (ITransaction transaction = session.BeginTransaction()) 
     { 
      session.Save(entity); 
      transaction.Commit(); 
     } 
    } 
} 

Cest très grande, mais je dois créer un référentiel pour chacune de mes entités de domaine comme suit:

public class ConnectionModel : AbstractNHibernate<Connection> 
    { 
     public void SaveConnection(Connection conn) 
{ 
Add(conn); 
} 
    } 

Je pourrais potentiellement avoir beaucoup de ceux-ci. Quelqu'un peut-il suggérer une approche différente?

Merci d'avance.

Répondre

2

Vos dépôts devraient (en général) sessions ouvertes ou non effectuer des transactions. Cela devrait être fait dans une couche de service ou dans l'interface utilisateur. Avec votre design actuel, il n'y a aucun moyen de faire participer plusieurs référentiels à la même transaction. Vous pouvez accomplir cela en exigeant l'ISession dans le constructeur du référentiel. Je n'aime pas non plus le référentiel unique par modèle d'objet, une meilleure approche consiste à regrouper logiquement les fonctions communes du référentiel. Par exemple, un CompanyRepository aurait des méthodes pour travailler avec des entreprises et des données connexes - CompanyType, CompanyStatus, etc.

0

La façon dont je l'ai vu faire (et comment je le fais) est d'établir une interface, créer une classe Nhiberate qui réalise cette interface (Pattern Repository)

http://www.rosscode.com/blog/index.php?title=the_repository_pattern_andash_iarsquo_m_&more=1&c=1&tb=1&pb=1

également l'utilisation de le modèle de spécification permet aux requêtes d'être transmises au référentiel. plus d'informations peuvent être trouvées ici:

http://www.mostlyclean.com/category/NHibernate.aspx

choses à noter est que la session est créé à un autre, puis injecté (passé) dans les dépôts, j'utilise un conteneur IoC comme Windsor pour le faire.

HTH

0

Peut-être que je ne comprends pas votre question? Vous semblez demander plus sur la façon d'implémenter les génériques afin que vous n'ayez pas à créer une classe spécifique à chaque objet plutôt que de poser une question nhibernate.

Voici un référentiel simple qui accepte tout type T. Vous supprimez simplement le T de la signature de classe et instanciez. Mais gardez à l'esprit que c'est un peu plus qu'un wrapper de session, plus une unité de travail qu'un référentiel. La mise en œuvre des requêtes nécessitera du travail pour essayer de rendre générique. Vous pouvez utiliser quelque chose comme ça comme classe de base pour un sous-type où vous avez besoin de requêtes complexes et aussi comme une instance autonome si vous ne supportez que des requêtes très basiques pour d'autres objets.

/// <summary> 
/// Repository defines simple class with standard methods 
/// to accept and operate on any type. 
/// </summary> 
public class Repository 
{ 
    private ISession _session; 

    public ISession Session 
    { 
     get { return _session; } 
    } 


    /// <summary> 
    /// Save an entity. 
    /// </summary> 
    public void Save<T>(T entity) 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Save(entity); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Update an entity 
    /// </summary> 
    public void Update<T>(T entity) 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Update(entity); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Delete an entity 
    /// </summary> 
    public void Delete<T>(T entity) 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Delete(entity); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Retrieve an entity 
    /// </summary> 
    public T GetById<T>(Guid id) 
    { 
     Reconnect(_session); 
     try 
     { 
      return _session.Get<T>(id); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Method for flushing the session. 
    /// </summary> 
    public void Flush() 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Flush(); 
      _session.Clear(); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Reconnect to the session. Accept parameter so we can use anywhere. 
    /// </summary> 
    public void Reconnect(ISession session) 
    { 
     if (!session.IsConnected) 
     { 
      session.Reconnect(); 
     } 
    } 

    /// <summary> 
    /// Disconnect from the session. Accept parameter so we can use anywhere. 
    /// </summary> 
    public void Disconnect(ISession session) 
    { 
     if (session.IsConnected) 
     { 
      session.Disconnect(); 
     } 
    } 

    public Repository(ISession session) 
    { 
     _session = session; 
    } 

} 

}

+0

pourquoi toutes les sessions reconnexions et déconnexions? – dbones

+0

J'ai eu la même question que dbones. – Nick

+0

Aucune bonne raison.Les déconnexions et les reconnexions immédiates et explicites autour de chaque action sont une exigence de politique qui vient d'un DBA qui est très anti-ORM et qui a essayé d'écraser tout le concept. Il a été renversé sur cela mais a eu assez de poids politique pour imposer quelques règles (souvent absurdes) sur le développement. Désolé pour toute confusion, après un moment, il devient l'habitude de faire les choses de cette façon. – Sisyphus

Questions connexes