Voy a permitir que Ninject administre mi estado ISession
y ITransaction
en Fluent nHibnerate con el siguiente método de registro: me pregunto si es suficiente el control de las transacciones o si necesito ponerme esto en otro lugarDeje que Ninject administre mi estado de transacción, practique inquietudes
La idea es que cada ISession
se crea en una solicitud, y que Ninject maneja la confirmación de todo lo hecho durante esa solicitud.
public class SessionModule : Ninject.Modules.NinjectModule
{
private static ISessionFactory sessionFactory;
public override void Load()
{
Bind<ISessionFactory>()
.ToMethod(c => CreateSessionFactory())
.InSingletonScope();
Bind<ISession>()
.ToMethod(c => OpenSession())
.InRequestScope()
.OnActivation(session =>
{
session.BeginTransaction();
session.FlushMode = FlushMode.Commit;
})
.OnDeactivation(session =>
{
if (session.Transaction.IsActive)
{
try
{
session.Flush();
session.Transaction.Commit();
}
catch
{
session.Transaction.Rollback();
}
}
});
}
/// <summary>
/// Create a new <see cref="NHibernate.ISessionFactory"/> to connect to a database.
/// </summary>
/// <returns>
/// A constructed and mapped <see cref="NHibernate.ISessionFactory"/>.
/// </returns>
private static ISessionFactory CreateSessionFactory()
{
if (sessionFactory == null)
sessionFactory = Persistence.SessionFactory.Map
(System.Web.Configuration
.WebConfigurationManager
.ConnectionStrings["Local"]
.ConnectionString
);
return sessionFactory;
}
/// <summary>
/// Open a new <see cref="NHibernate.ISession"/> from a <see cref="NHibernate.ISessionFactory"/>.
/// </summary>
/// <returns>
/// A new <see cref="NHibernate.ISession"/>.
/// </returns>
private static ISession OpenSession()
{
// check to see if we even have a session factory to get a session from
if (sessionFactory == null)
CreateSessionFactory();
// open a new session from the factory if there is no current one
return sessionFactory.OpenSession();
}
}
He examinado el tiempo de ejecución usando System.Diagnostics.Debug.WriteLine
a escribir cuando ocurren las cosas, y lo hace aspecto que presentan está haciendo lo que quería que haga. Lo que le estoy preguntando, la comunidad, es si esta es una buena práctica o no. Aquí está mi entendimiento.
Innumerables horas de lectura en http://ayende.com/blog/default.aspx me han llevado a reevaluar gran parte de la forma en que manejo la sesión.
Una gran cantidad de excavación en la documentación nHibernate me dice que necesito usar ITransaction
cada vez que pasa algo con mi base de datos.
La colocación de la gestión en un atributo se considera un error, ya que no se adhiere a la instrucción mencionada anteriormente.
Haciendo ITransaction
por operación individual no es el proceso correcto, porque requeriría bien (a) mis controladores de tener acceso a la ISession
o (B) Mi IRepository<T>
tener la lógica ITransaction
, que me han dicho en los anteriores preguntas no era una buena práctica.
La colocación de mi ITransaction
de gestión en un HttpModule
implica una sobrecarga no-lo necesite, ya que da mi conocimiento HttpContext del ISession
y eso significa que tengo que hacer algún tipo de inyección en el HttpRequest
(que yo puedo hacer uso de [Inject]
, pero no parece sabio)
Esto me ha llevado a esta conclusión.
- Las transacciones deben comenzar cuando se solicita una
ISession
. - Todo lo que sucede en una sola petición está encapsulada por una
ISession
- Cuando un
ITransaction
se hace, tiene que ser cometido de manera que el segundo nivel de caché puede obtener sus resultados.
¿Alguien puede arrojar luz sobre esto? ¿Estoy finalmente en el camino correcto? ¿O todavía me he perdido el punto por completo?
Me preguntaba si hay una manera de conectar en 'InRequestScope' para iniciar/confirmar la transacción ... Gracias por tu mensaje! – user1068352