Espacio de Dario Quintana

What are payday loans Payday Loans UK How much can you borrow

NHibernate + EventListeners + "Cualquier Framework de Validación"

En este post estaba adelantando algo que estoy empezando a hacer, por ahora bosquejando y pensando, sin embargo…hay algo funcional para ir pispeando.

La idea es crear un "puente" entre NHibernate y diferentes frameworks para validar nuestras entidades de negocio. Hay quienes les gusta validar solamente en la entrada, otros en la capa de negocio, otros en la capa de acceso a datos, u otros en todos lados! Este "approach" intentará validar en la capa de Acceso a datos, justo antes de que NHibernate realice un Save/Update (y por que no un Delete?).

Por ahora, pueden encontrar el código disponible para usar haciendo un checkout de SVN de uNHAddIns. Consta de un proveedor para usar el validador del Enterprise Library Application Block . Después veremos que otros frameworks podemos inyectar (para eso necesito sus sugerencias).

Como pueden ver en este test, NHibernate arroja una excepción si alguien intenta guardar una entidad no válida. Créanme que arroja luz verde.

[Test,ExpectedException(typeof(ValidationException))] public void InsertWithInvalidEntity() { using (ISession s = sf.OpenSession()) { using (ITransaction tx = s.BeginTransaction()) { s.Save(GetNoValidFoo()); tx.Commit(); } } }

Para poder configurar este escenario es necesario una configuración previa como esta:

cfg = new Configuration(); cfg.SetProperty(Environment.HibernateValidationProvider, typeof(EntLibValidator).AssemblyQualifiedName); ValidateEventListener validateEventListener = new ValidateEventListener(); cfg.SetListener(ListenerType.PreInsert, validateEventListener); cfg.SetListener(ListenerType.PreUpdate, validateEventListener); cfg.Configure(); sf = cfg.BuildSessionFactory();

El EventListener ValidateEventListener hace el trabajo de intercepción antes de las operaciones Insert/Update, de ese modo es como podemos hacer el trabajo de validación.

Esto es un borrador, que por cierto funciona, así que puede cambiar. Todo comentario es más que bienvenido.

Para hacer checkout de el código fuente:

http://unhaddins.googlecode.com/svn/branches/NHTrunk/

3 layer Example of NHibernate + Spring.Net + AOP

Hace un tiempo escribí este proyecto plantilla usando Spring.Net y NHibernateprincipalmente. Usé NHibernate para el acceso a datos obviamente y Spring.Net para aplicar IoC y Aop.

Esta es la clase CustomerService:

    public class CustomerService : BaseService, ICustomerService
    {
	/// <summary>
        /// This field is inyected by IoC through the property.
        /// </summary>

        private ICustomerDao customerDao;        
 	public ICustomerDao CustomerDao {
            get { return customerDao; }
          set { customerDao = value; }
        }

#region ICustomerService Members

	public int CreateCustomer(string Name, string LastName) {

        	Customer customer = new Customer();

        	customer.FirstName = "Dario";

	        customer.LastName = "Quintana";

		CustomerDao.Save(customer);

		return customer.Id;

        }

	public void DeleteCustomer(int Id) {

            	Customer customer = CustomerDao.GetById(Id);

		CustomerDao.Delete(customer);

        }

#endregion

    }

Como se puede apreciar las clases CreateCustomer ó DeleteCustomer no están envueltas en un codigo Transactional o de UnitOfWork, tampoco el método Save(customer) en la clase CustomerDao.

Entonces… donde está el soporte transaccional? Spring + AOP es la respuesta. Spring envuelve a los metodos del Servicio entre transacciones. Y la respuesta para esto son los proxies.

Cuando se realiza la instanciación de la clase CustomerService, un proxy es instanciado. Con el proxy de nuestra clase Spring.Net puede envolver los metodos configurados dentro de transacciones. Muy bueno no ?

Otra cosa que pueden apreciar en el ejemplo es el uso de uNhAddIns en el repositorio. Con esta librería podemos usar queries "detachadas" o separadas de un contexto de persistencia por medio de la clase DetachedQuery. Con DetachedQuery podemos hacer uso indistinto de Hql/SqlNativo en NamedQueries, y esto es una buena práctica que debemos tratar de adoptar.

Descargar el ejemplo

ActiveRecord con soporte para DetachedQuery

[English post]

Este fin de semana escribí las clases necesarias para el soporte de IDetachedQuery con ActiveRecord. DetachedQuery no está disponible todavía en ninguna versión de NHibernate, la podés encontrar solamente en uNHAddInsy en el SVN de NHibernate.

Agregué un proyecto a uNHAddIns: uNHAddIns.ActiveRecord. Este consiste en las clasicas clases de ActiveRecord pero con soporte para DetachedQuery.

Si queres este soporte, tenés que usar estas clases:

  • ActiveRecordBase
  • ActiveRecordBase<T>
  • ActiveRecordValidationBase
  • and ActiveRecordValidationBase<T>

Y vas a poder hacer cosas como por ejemplo:

Customer[] customers = Customer.FindAll(new DetachedQuery("from Customer Order By Name"));

Los nuevos métodos para ActiveRecordBase y ActiveRecordValidationBase son:

  • public static bool Exists(Type targetType, IDetachedQuery detachedQuery);
  • public static Array FindAll(Type targetType, IDetachedQuery detachedQuery);
  • public static object FindFirst(Type targetType, IDetachedQuery detachedQuery);
  • public static object FindOne(Type targetType, IDetachedQuery detachedQuery);
  • public static Array SlicedFindAll(Type targetType, int firstResult, int maxResults, IDetachedQuery detachedQuery);

Y los nuevos metodos para ActiveRecordBase<T> y ActiveRecordValidationBase<T> son:

  • public static bool Exists(IDetachedQuery detachedQuery);
  • public static T[] FindAll(IDetachedQuery detachedQuery);
  • public static T FindFirst(IDetachedQuery detachedQuery);
  • public static T FindOne(IDetachedQuery detachedQuery);
  • public static T[] SlicedFindAll(int firstResult, int maxResults, IDetachedQuery detachedQuery);

Esta implementación no oculta ninguna característica de las clases base de ActiveRecord, son una extensión para el soporte para IDetachedQuery.

Requerimientos

Las clases están en el ensamblado uNHAddIns.ActiveRecord.dll. Y este ensamblado requiere del principal: uNHAddIns.dll.

Descargas

Entrada en la Wiki

Validación en NHibernate

Una de las puertas que dejó abierta el port de EventListeners, es la posibilidad de crear algunas clases para poder validar objetos antes de ser guardados (como así también antes de ser borrados).

Una opción es portar Hibernate.Validator, pero… alguién realmente va a usarlo? Yo personalmente creo que no. Mirando su implementación y qué hace, no ofrece mucho más de lo que se puede encontrar del lado de .Net con algunas librerías. Quizás algún día se porte Hibernate.Validator, pero por ahora, yo creo que es más importante portar algunas otras features de Hibernate, estas se van a aprovechar más.

Una opción valida, es crear bridges entre NHibernate (EventListeners) y algunos frameworks conocidos en .Net para la validación de entradas (input validation).

Algunas opciones que se me ocurren:

La implementación ya sea Hibernate.Validator (no creo) o algún bridge para los mencionados, se hará en uNHAddIns.

Un punto interesante, sería que posea la posilidad de extensibilidad para validadores hechos por nosotros.

uNHAddIns new release available – Revision 64

By internal policies uNHAddins not have yet a release number o release version name, by now we are using the revision number at SVN for this purpose. Probably will come a branch when NHibernate 2.0 release appear, and that will be the time.

Download here

Features of new version:

  • Added UserType: UpperString. Allow save/get strings against the database in upper case.
  • Few features at pagination.
  • Documentation enhanced.
  • Cloner helper for make objects clone via binary serialization.
  • Build files for compiler using NAnt.

For more resources visit:

[In Spanish]

Por politicas internas uNHAddIns todavía no tiene asignado numero o version de Release, por ahora estamos usando el número de revision para esto. Ya vendrá seguramente un branch para usar NHibernate 2.0 cuando sea release, y ese será el momento.

Descarga aquí

En la nueva versión se incluyen:

  • Nuevo UpperString User Type. Permite guardar/obtener los string en mayúsculas (upper case).
  • Algunas caracteristicas nuevas en la paginación (pocas)
  • Se ha mejorado la documentación.
  • Un Cloner para clonar objetos mediante serialización binaria. Simple helper.
  • Soporta compilación usando NAnt.

Para más recursos visitá:

uNHAddins: UnOfficial NHibernate AddIns

Fabio Maulo, con quien tengo el honor de moderar a NHibernate-Hispano, ah puesto a nuestra disposición este nuevo proyecto llamado uNHAddIns.

UnOfficial NHibernate Addins nos provee recursos para interactuar con NHibernate que no están en la versión Oficial de NHibernate, una especie de paquete Contrib, al cual podemos hacer llegar requerimientos ó inquietudes para tenerlas en cuenta y en un futuro hacerlas formar parte del framework.

Por ahora,  ya podemos disfrutar de features: DetachedCriteria, DetachedQuery, DetachedDynQuery y Pagination.

DetachedQuery es el hermano de DetachedCriteria. DetachedCriteria existe actualmente en el core de NHibernate, pero no habia algo similar para HQL.

Se utiliza DetachedQuery/DetachedCriteria en lugares donde no contamos con una ISession. Es un modo de retardar hasta el ultimo momento la asociación del query con la sesión y esto ayuda a jugar mucho en las implementaciones de DAO Genericas.

Recursos:

Luego postearé codigos de ejemplo, pero pueden unirse al grupo de discución para hacer llegar las preguntas.