Tengo una configuración de patrón de repositorio utilizando NHibernate. La clase base es el siguiente:Unidad de trabajo y el patrón de repositorio
public interface IUnitOfWork : IDisposable
{
void Commit();
void Rollback();
}
// generic NHibernate implementation of IUnitOfWork here
public class NHibernateRepositoryBase<T> : IRepository<T>
{
private NHibernateUnitOfWork _unitOfWork;
public NHibernateRepositoryBase(NHibernateUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public T Get(object id)
{
return _unitOfWork.Session.Get<T>(id);
}
// ...
}
Como se puede ver, estoy permitiendo que la unidad de trabajo que se rellena a través de la constructora (usando StructureMap). Estoy instalando los objetos del repositorio en mis servicios web ASP.NET, así:
[WebService(Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ModuleService : System.Web.Services.WebService
{
public IUserAccountRepository UserAccountRepo { get; set; }
public ModuleService()
{
// tell IoC to inject properties
ObjectFactory.BuildUp(this);
}
// ...
}
Como es posible que pueda deducir, mi problema es que por medio del diseño, ahora he perdido el control del ciclo de vida de la unidad de trabajo. Anteriormente, he hecho la unidad de trabajo un objeto sensible al contexto y el repositorio gustaría obtener una referencia a la misma a través de algo como:
public class NHibernateRepositoryBase<T> : IRepository<T>
{
public T Get(object id)
{
return NHibernateUnitOfWork.GetCurrent().Session.Get<T>(id);
}
// ...
}
Este diseño anterior me permitió controlar el ciclo de vida de la unidad de trabajo en mi código creando la unidad de trabajo de un UnitOfWorkFactory dentro de una instrucción using. Estaba tratando de poner más trabajo en las manos del contenedor IoC, pero creo que realmente di un paso atrás. ¿Cuáles son sus pensamientos sobre cualquiera de las implementaciones?
¿Cómo se manejan las transacciones individuales en ese tipo de configuración? Digamos que necesito ejecutar dos juegos separados de código dentro de la misma sesión, y cada uno tiene su propia transacción. ¿Cómo recomendarías manejar eso? – Chris
Las transacciones se manejan a través de la sesión. No necesita nada más que la referencia de sesión para usar una transacción. –
La sesión de NHibernate es básicamente una unidad de trabajo en sí misma. La razón para esconderlo detrás de su propia interfaz de unidad de trabajo es básicamente para que pueda exponerlo de manera genérica al resto de la aplicación (fuera de su repositorio) y no depender de NHibernate. Y eso solo será inicializarlo al inicio de la solicitud y comprometerlo al final. –