¿Alguien puede proporcionar/referir una clase de ayuda de tipo OO apropiada para administrar un singleton de SessionFactory y luego también para gestionar Sessions?NHibernate - buena clase completa de trabajo de ayuda para administrar SessionFactory/Session
Respuesta
Sin duda, esto es lo que usé cuando estaba empezando con NHibernate:
Sesión fábrica
public class BaseDataAccess
{
protected ISession m_session;
public BaseDataAccess()
{
m_session=NHibernateHttpModule.CurrentSession;
}
public static ISession OpenSession()
{
Configuration config;
ISessionFactory factory;
ISession session;
config = new Configuration();
if (config==null)
{
throw new InvalidOperationException("NHibernate configuration is null.");
}
config.AddAssembly("My.Assembly.Here");
factory = config.BuildSessionFactory();
if (factory==null)
{
throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null.");
}
session = factory.OpenSession();
if (session==null)
{
throw new InvalidOperationException("Call to factory.OpenSession() returned null.");
}
return session;
}
}
Quiero saber si eso ayuda.
¡Gracias! Esto es útil, pero estoy buscando algo que sea un poco más robusto.
Por ejemplo, al hacer referencia en el sitio NH (http://hibernate.org/363.html#A9) es una contribución realizada por Andrew Mayorov y publica tres archivos como este (http://nhibernate.sourceforge.net/contrib/Wiki_AndrewMayorovAspNet.zip).
Lo que pasa es que no viene con mucha ayuda. No estoy exactamente seguro de cómo usarlo correctamente. Intenté algunas cosas, pero tuve problemas.
¿Alguien tiene algo que utiliza esto o similar?
Echa un vistazo Billy McCafferty's work. Su versión anterior tenía algunas limitaciones, necesitarás corregir el manejo del error al cerrar y enrojar, y no estoy seguro de que esté bien, pero publicaré cómo modifiqué sus cosas.
Billy también está trabajando en un nuevo marco que utiliza MVC & nHibernate llamado S #arp Architechure que estoy usando actualmente, y hasta ahora todo va bien.
De todos modos aquí está mi versión modificada de su código. No hago guantas sobre la precisión o la completitud y lo está utilizando bajo su propio riesgo. Si usa esto, asegúrese de cerrar la sesión. Si tienes alguna pregunta, envíame un correo electrónico [joshua] [dot] [berke] a [gmail ... ya sabes el resto].
/// <summary>
/// Handles creation and management of sessions and transactions. It is a singleton because
/// building the initial session factory is very expensive. Inspiration for this class came
/// from Chapter 8 of Hibernate in Action by Bauer and King. Although it is a sealed singleton
/// you can use TypeMock (http://www.typemock.com) for more flexible testing.
/// </summary>
public sealed class NHibernateSessionManager
{
private const string DefaultConfigFile = "DefaultAppWeb.Config";
private static readonly object _syncRoot = new object();
#region Thread-safe, lazy Singleton
/// <summary>
/// This is a thread-safe, lazy singleton. See http://www.yoda.arachsys.com/csharp/singleton.html
/// for more details about its implementation.
/// </summary>
public static NHibernateSessionManager Instance
{
get
{
return Nested.NHibernateSessionManager;
}
}
/// <summary>
/// Private constructor to enforce singleton
/// </summary>
private NHibernateSessionManager() { }
/// <summary>
/// Assists with ensuring thread-safe, lazy singleton
/// </summary>
private class Nested
{
static Nested() { }
internal static readonly NHibernateSessionManager NHibernateSessionManager =
new NHibernateSessionManager();
}
#endregion
/// <summary>
/// This method attempts to find a session factory stored in <see cref="sessionFactories" />
/// via its name; if it can't be found it creates a new one and adds it the hashtable.
/// </summary>
/// <param name="sessionFactoryConfigPath">Path location of the factory config</param>
private ISessionFactory GetSessionFactoryFor(string sessionFactoryConfigPath)
{
Check.Require(!string.IsNullOrEmpty(sessionFactoryConfigPath),
"sessionFactoryConfigPath may not be null nor empty");
// Attempt to retrieve a stored SessionFactory from the hashtable.
ISessionFactory sessionFactory;// = (ISessionFactory)sessionFactories[sessionFactoryConfigPath];
// try and get a session factory if we don't find one create it
lock (_syncRoot)
{
if (!sessionFactories.TryGetValue(sessionFactoryConfigPath, out sessionFactory))
{
Configuration cfg = new Configuration();
if (sessionFactoryConfigPath != DefaultConfigFile)
{
Check.Require(File.Exists(sessionFactoryConfigPath),
"The config file at '" + sessionFactoryConfigPath + "' could not be found");
cfg.Configure(sessionFactoryConfigPath);
}
else
{
cfg.Configure();
}
// Now that we have our Configuration object, create a new SessionFactory
sessionFactory = cfg.BuildSessionFactory();
Check.Ensure(sessionFactory != null, "sessionFactory is null and was not built");
sessionFactories.Add(sessionFactoryConfigPath, sessionFactory);
}
}
return sessionFactory;
}
/// <summary>
/// Allows you to register an interceptor on a new session. This may not be called if there is already
/// an open session attached to the HttpContext. If you have an interceptor to be used, modify
/// the HttpModule to call this before calling BeginTransaction().
/// </summary>
public void RegisterInterceptorOn(string sessionFactoryConfigPath, IInterceptor interceptor)
{
ISession session = (ISession)ContextSessions[sessionFactoryConfigPath];
if (session != null && session.IsOpen)
{
throw new CacheException("You cannot register an interceptor once a session has already been opened");
}
GetSessionFrom(sessionFactoryConfigPath, interceptor);
}
public ISession GetSessionFrom(string sessionFactoryConfigPath)
{
return GetSessionFrom(sessionFactoryConfigPath, null);
}
/// <summary>
/// Gets or creates an ISession using the web/app config file.
/// </summary>
/// <returns></returns>
public ISession GetSessionFrom()
{
return GetSessionFrom(DefaultConfigFile, null);
}
/// <summary>
/// Gets a session with or without an interceptor. This method is not called directly; instead,
/// it gets invoked from other public methods.
/// </summary>
private ISession GetSessionFrom(string sessionFactoryConfigPath, IInterceptor interceptor)
{
var allSessions = ContextSessions;
ISession session = null;
if (!allSessions.TryGetValue(sessionFactoryConfigPath, out session))
{
if (interceptor != null)
{
session = GetSessionFactoryFor(sessionFactoryConfigPath).OpenSession(interceptor);
}
else
{
session = GetSessionFactoryFor(sessionFactoryConfigPath).OpenSession();
}
allSessions[sessionFactoryConfigPath] = session;
}
//session.FlushMode = FlushMode.Always;
Check.Ensure(session != null, "session was null");
return session;
}
/// <summary>
/// Flushes anything left in the session and closes the connection.
/// </summary>
public void CloseSessionOn(string sessionFactoryConfigPath)
{
ISession session;
if (ContextSessions.TryGetValue(sessionFactoryConfigPath, out session))
{
if (session.IsOpen)
{
session.Flush();
session.Close();
}
ContextSessions.Remove(sessionFactoryConfigPath);
}
}
public ITransaction BeginTransactionOn(string sessionFactoryConfigPath)
{
ITransaction transaction;
if (!ContextTransactions.TryGetValue(sessionFactoryConfigPath, out transaction))
{
transaction = GetSessionFrom(sessionFactoryConfigPath).BeginTransaction();
ContextTransactions.Add(sessionFactoryConfigPath, transaction);
}
return transaction;
}
public void CommitTransactionOn(string sessionFactoryConfigPath)
{
try
{
if (HasOpenTransactionOn(sessionFactoryConfigPath))
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath];
transaction.Commit();
ContextTransactions.Remove(sessionFactoryConfigPath);
}
}
catch (HibernateException he)
{
try
{
RollbackTransactionOn(sessionFactoryConfigPath);
}
finally
{
throw he;
}
}
}
public bool HasOpenTransactionOn(string sessionFactoryConfigPath)
{
ITransaction transaction;
if (ContextTransactions.TryGetValue(sessionFactoryConfigPath, out transaction))
{
return !transaction.WasCommitted && !transaction.WasRolledBack;
}
return false;
}
public void RollbackTransactionOn(string sessionFactoryConfigPath)
{
try
{
if (HasOpenTransactionOn(sessionFactoryConfigPath))
{
ITransaction transaction = (ITransaction)ContextTransactions[sessionFactoryConfigPath];
transaction.Rollback();
}
ContextTransactions.Remove(sessionFactoryConfigPath);
}
finally
{
ForceCloseSessionOn(sessionFactoryConfigPath);
}
}
/// <summary>
/// Since multiple databases may be in use, there may be one transaction per database
/// persisted at any one time. The easiest way to store them is via a hashtable
/// with the key being tied to session factory. If within a web context, this uses
/// <see cref="HttpContext" /> instead of the WinForms specific <see cref="CallContext" />.
/// Discussion concerning this found at http://forum.springframework.net/showthread.php?t=572
/// </summary>
private Dictionary<string, ITransaction> ContextTransactions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[TRANSACTION_KEY] == null)
HttpContext.Current.Items[TRANSACTION_KEY] = new Dictionary<string, ITransaction>();
return (Dictionary<string, ITransaction>)HttpContext.Current.Items[TRANSACTION_KEY];
}
else
{
if (CallContext.GetData(TRANSACTION_KEY) == null)
CallContext.SetData(TRANSACTION_KEY, new Dictionary<string, ITransaction>());
return (Dictionary<string, ITransaction>)CallContext.GetData(TRANSACTION_KEY);
}
}
}
/// <summary>
/// Since multiple databases may be in use, there may be one session per database
/// persisted at any one time. The easiest way to store them is via a hashtable
/// with the key being tied to session factory. If within a web context, this uses
/// <see cref="HttpContext" /> instead of the WinForms specific <see cref="CallContext" />.
/// Discussion concerning this found at http://forum.springframework.net/showthread.php?t=572
/// </summary>
private Dictionary<string, ISession> ContextSessions
{
get
{
if (IsInWebContext())
{
if (HttpContext.Current.Items[SESSION_KEY] == null)
HttpContext.Current.Items[SESSION_KEY] = new Dictionary<string, ISession>();
return (Dictionary<string, ISession>)HttpContext.Current.Items[SESSION_KEY];
}
else
{
if (CallContext.GetData(SESSION_KEY) == null)
CallContext.SetData(SESSION_KEY, new Dictionary<string, ISession>());
return (Dictionary<string, ISession>)CallContext.GetData(SESSION_KEY);
}
}
}
private bool IsInWebContext()
{
return HttpContext.Current != null;
}
private Dictionary<string, ISessionFactory> sessionFactories = new Dictionary<string, ISessionFactory>();
private const string TRANSACTION_KEY = "CONTEXT_TRANSACTIONS";
private const string SESSION_KEY = "CONTEXT_SESSIONS";
public bool HasOpenTransactionOn()
{
return HasOpenTransactionOn(DefaultConfigFile);
}
public void CommitTransactionOn()
{
CommitTransactionOn(DefaultConfigFile);
}
public void CloseSessionOn()
{
CloseSessionOn(DefaultConfigFile);
}
public void ForceCloseSessionOn()
{
ForceCloseSessionOn(DefaultConfigFile);
}
public void ForceCloseSessionOn(string sessionFactoryConfigPath)
{
ISession session;
if (ContextSessions.TryGetValue(sessionFactoryConfigPath, out session))
{
if (session.IsOpen)
{
session.Close();
}
ContextSessions.Remove(sessionFactoryConfigPath);
}
}
public void BeginTransactionOn()
{
this.BeginTransactionOn(DefaultConfigFile);
}
public void RollbackTransactionOn()
{
this.RollbackTransactionOn(DefaultConfigFile);
}
}
cosas buenas. Usando NH 3.2, funciona muy bien con un mod: tuve que cambiar 'HasOpenTransactionOn' para usar' transaction.IsActive'. [Aquí está el por qué] (http://stackoverflow.com/a/1007633/612265). –
¡Oh, qué bueno! Muchas gracias – JoshBerke
recomiendo echarle un vistazo Rhino Commons biblioteca Ayende 's. El documentation es un poco escaso en este momento, pero una vez que esté en funcionamiento, trabajar con NHibernate será MUCHO más fácil.
He tenido un gran éxito en el pasado utilizando los módulos de soporte NHibernate de Spring.NET. Ver http://www.springframework.net/downloads/Spring.Data.NHibernate/. Debería poder usar el módulo OpenSessionInView y extender sus DAO fuera del NHibernateSupport DAO para obtener soporte completo de administración del open session in view pattern.
Además, aunque nunca lo he probado, debería poder utilizar el marco anteriormente mencionado incluso si opta por no restablecer las ofertas de Spring.NET (concretamente IoC y AOP).
He escrito un blog post sobre esto donde utilizo la implementación web administrada de manejo de sesión contextual. Tal vez eso es lo que estás buscando?
NHibernate Burrow parece prometedor. Empecé a usarlo y no tengo problemas hasta la fecha.
Dos sugerencias:
- HybridSessionBuilder de Jeffrey Palermo (jeffreypalermo.com/blog/use-this-nhibernate-wrapper-to-keep-your-repository-classes-simple)
- Ver los ejemplos de código (ver específicamente Sesión 13) en el verano de NHibernate (www.summerofnhibernate.com)
Es posible que desee considerar la posibilidad de su DAL menos que ver con la gestión de sesiones de NHibernate mediante el aprovechamiento de NHibernate.Burrow (o la aplicación de un patrón similar a sí mismo)
"NHibernate.Burrow es un middleware liviano desarrollado para admitir aplicaciones .Net que utilizan NHibernate al proporcionar una gestión de sesión/transacción inteligente y avanzada y otras funciones más fáciles".
Si decide rodar su propia hay algunos enlaces útiles en la parte inferior de esta página:
Un término de búsqueda Google útil sería 'Gestión de la sesión de NHibernate' y 'Sesiones contextuales' ...
No hay escasez de ideas; podría decirse que hay demasiadas opciones, con suerte la opinión comenzará a gravitar alrededor de Burrow o algo así ...
- 1. Buena recomendación tutorial de NHibernate ayuda
- 2. Herramientas gratuitas de ayuda de NHibernate?
- 3. ¿Qué consideraría una buena ayuda de Eclipse?
- 4. Fluidez NHibernate: ¿Cómo asignar una clase completa como ReadOnly?
- 5. Ayuda de apertura en una ventana completa
- 6. Unidad de trabajo/administradores de repositorios para NHibernate?
- 7. ¿Existe una buena utilidad/biblioteca de terceros para administrar el almacén de datos de AppEngine?
- 8. ¿La mejor manera de administrar sesiones en NHibernate?
- 9. UML - ¿Cómo administrar diagramas de clase grande?
- 10. ¿Cuál es una buena clase de muestra para demostrar TDD?
- 11. ¿Alguna buena solución para un sistema de ayuda integrado en las aplicaciones de WPF?
- 12. Software para administrar historias de usuarios
- 13. Buena solución C# .NET para administrar sondeos de bases de datos frecuentes
- 14. Magento - crear una clase de ayuda
- 15. cuando se completa el trabajo de una función
- 16. nhibernate y propiedades de clase virtual?
- 17. ¿Cómo administrar las sesiones de NHibernate en una aplicación de formularios de Windows de larga vida?
- 18. es dormir() una buena idea para el bucle principal de una aplicación de trabajo de programación
- 19. ¿Cuál es una buena forma de administrar los commits de limpieza en git para un proyecto heredado?
- 20. Administrar historias de usuarios para un proyecto grande
- 21. Administrar caché de MapView
- 22. ¿Cuál es una buena forma de administrar las notificaciones locales que ha programado su aplicación?
- 23. ¿Es una buena idea conectar al compositor para administrar recursos web en Symfony2?
- 24. Cómo bloquear un método para una clase completa usando sincronizado?
- 25. Utilizando la clase HelpProvider para mostrar ayuda, la interfaz de usuario siempre está detrás de la ventana de ayuda
- 26. ¿Sugerencias para administrar dependencias para una versión?
- 27. ¿Buena alternativa para ASpell?
- 28. Visual Studio: sugerencias para administrar el trabajo en muchos archivos abiertos
- 29. ¿Cuándo es una buena situación usar una unión externa completa?
- 30. GUI para administrar los filtros de Gmail?
¿Qué quiere decir con 'robusto'? ¿Puedes ser más explícito en cuanto a lo que falta? ¿Qué intentaste? ¿Y con qué problema te topaste? Tuve problemas cuando comencé con NHibernate, por lo que me gustaría ayudar si es posible. –