21/01/09

NHibernate: Aplicando Patrones de diseño a una aplicación que utiliza NHibernate – Parte 2

Hola a todos, siguiendo con el post anterior, en este nuevo post implementaremos la Capa de Logica de Negocios de nuestra aplicación de ejemplo.

(*) Los Archivos de mapeo (hbm) lo pueden generar a partir de MyGeneration como es mi caso. en todo caso no los puse en el post anterior.

Bueno regresemos, Al igual que en nuestra capa de datos, donde se implemento abstract factory , en nuestra capa de negocios tambien implementaremos abstrac factory de manera similar.

image

Entonces la implementación seria la siguiente:

La Interfaz IGenericController:

La interfaz declara los metodos genericos para la manipulación de nuestras entiades de negcios.

using System.Collections;
using System.Collections.Generic;

namespace NHBussines
{
public interface IGenericController<T,Id>
{
T FindByid(Id id);

IList<T> FindAll();

IList<T> FindAllOrdered(IList<string> propertyNames);

IList<T> FindByExample(T entity);

IList<T> FindBydExampleOrdered(T entity, IList<string> propertyNames);

IList<T> FindLikeExample(T entity);

IList<T> FindLikeExampleOrdered(T entity, IList<string> propertyNames);

IList<T> FindLikeExampleIgnoreCase(T entity);

IList<T> FindLikeExampleIgnoreCaseOrdered(T entity, IList<string> propertyNames);

IList<T> FindByQuery(string query);

IList<T> FindByQuery(string query, string[] parameters, object[] values);

IList<T> FindByNamedQuery(string query);

IList<T> FindByNamedQuery(string query, string[] parameters, object[] values);

IList FindObjectsByQuery(string query);

IList FindObjectsByNamedQuery(string query);

IList FindObjectsByNamedQuery(string query, string[] parameteres, object[] values);

IList FindObjectsBySQLQuery(string query, string[] parameters, object[] values);

T Save(T entity);

T Update(T entity);

void DeleteById(Id id);

void Delete(T entity);

Id GetMax(string propertyName);
}
}

GenericController:

Implementa la Interfaz IGenericController, atravez del GenericDAO, Tambien implementa el Metodo Instance , como la clase GenericControler es una clase abstracta esta no puede instarciarse utilizando el operador new(), utilizando este Metodo podemos instanciar esta clase abstracta.

Tambien es importante mencionar que para los metodos de CRUD, utilizamos los métodos de transaccionalidad de Nhibernate, estos metodos estan provistos por la clase estatica NHibernateHelper, Estos Metodos son:

BeginTransacction(); Inicializa una transaccion

EndTransacction(); Finaliza la trasaccion y reliza el repectivo commit

RollbackTransacction(); Hace una vuelta atras o rollback a la transaccion.

using System;
using System.Collections.Generic;
using System.Collections;
using NHDao;
using NHDataAccess;
namespace NHBussines
{
public abstract class GenericController<T,Id> : IGenericController<T,Id>
{
private DAOFactory daoFactory = DAOFactory.Instance(DAOFactory.DAO_FACTORY);

public DAOFactory DaoFactory
{
set
{
daoFactory = value;
}
get
{
return daoFactory;
}
}

public IGenericDAO<T, Id> GenericDao { get; set; }

public T FindByid(Id id)
{
return GenericDao.FindByid(id);
}

public IList<T> FindAll()
{
return GenericDao.FindAll();
}

public IList<T> FindAllOrdered(IList<string> propertyNames)
{
return GenericDao.FindAllOrdered(propertyNames);
}

public IList<T> FindByExample(T entity)
{
return GenericDao.FindByExample(entity);
}

public IList<T> FindBydExampleOrdered(T entity, IList<string> propertyNames)
{
return GenericDao.FindBydExampleOrdered(entity, propertyNames);
}

public IList<T> FindLikeExample(T entity)
{
return GenericDao.FindLikeExample(entity);
}

public IList<T> FindLikeExampleOrdered(T entity, IList<string> propertyNames)
{
return GenericDao.FindBydExampleOrdered(entity, propertyNames);
}

public IList<T> FindLikeExampleIgnoreCase(T entity)
{
return GenericDao.FindLikeExampleIgnoreCase(entity);
}

public IList<T> FindLikeExampleIgnoreCaseOrdered(T entity, IList<string> propertyNames)
{
return GenericDao.FindLikeExampleIgnoreCaseOrdered(entity, propertyNames);
}

public IList<T> FindByQuery(string query)
{
return GenericDao.FindByQuery(query);
}

public IList<T> FindByQuery(string query, string[] parameters, object[] values)
{
return GenericDao.FindByQuery(query, parameters, values);
}

public IList<T> FindByNamedQuery(string query)
{
return GenericDao.FindByNamedQuery(query);
}

public IList<T> FindByNamedQuery(string query, string[] parameters, object[] values)
{
return GenericDao.FindByNamedQuery(query, parameters, values);
}

public IList FindObjectsByQuery(string query)
{
return GenericDao.FindObjectsByQuery(query);
}

public IList FindObjectsByNamedQuery(string query)
{
return GenericDao.FindObjectsByNamedQuery(query);
}

public IList FindObjectsByNamedQuery(string query, string[] parameteres, object[] values)
{
return GenericDao.FindObjectsByNamedQuery(query,parameteres,values);
}

public IList FindObjectsBySQLQuery(string query, string[] parameters, object[] values)
{
return GenericDao.FindObjectsBySQLQuery(query, parameters, values);
}

public T Save(T entity)
{
T newEntity;
try
{
NHibernateHelper.BeginTransaction();
newEntity = GenericDao.Save(entity);
NHibernateHelper.EndTransaction();
}
catch (Exception ex)
{
NHibernateHelper.RollBackTransaction();
throw ex;
}
finally
{
NHibernateHelper.CloseSession();
}
return newEntity;
}

public T Update(T entity)
{
T newEntity;
try
{
NHibernateHelper.BeginTransaction();
newEntity = GenericDao.Update(entity);
NHibernateHelper.EndTransaction();
}
catch (Exception ex)
{
NHibernateHelper.RollBackTransaction();
throw ex;
}
finally
{
NHibernateHelper.CloseSession();
}
return newEntity;
}

public void Delete(T entity)
{
try
{
NHibernateHelper.BeginTransaction();
GenericDao.MakeTransient(entity);
NHibernateHelper.EndTransaction();
}
catch (Exception ex)
{
NHibernateHelper.RollBackTransaction();
throw ex;
}
finally
{
NHibernateHelper.CloseSession();
}
}
public void DeleteById(Id id)
{
try
{
NHibernateHelper.BeginTransaction();
GenericDao.MakeTransient(FindByid(id));
NHibernateHelper.EndTransaction();
}
catch (Exception ex)
{
NHibernateHelper.RollBackTransaction();
throw ex;
}
finally
{
NHibernateHelper.CloseSession();
}
}

public Id GetMax(string propertyName)
{
return GenericDao.GetMax(propertyName);
}
}
}

NHBussinessFactory:

Esta clase hereda de la clase BussinessFactory, que es la clase abstracta que provee los metodos abstractos que nos retornan de objetos de nuestras entidades de negocios

using NHBussines.Implementations;
using NHBussines.Interfaces;
namespace NHBussines
{
public class NHBussinesFactory : BussinesFactory
{
public override IRoleController GetRoleController()
{
return new RoleController();
}
public override IUserController GetUserController()
{
return new UserController();
}
public override IUserRoleController GetUserRoleController()
{
return new UserRoleController();
}
}
}

BussinessFactory

using System;
using NHBussines.Interfaces;

namespace NHBussines
{
public abstract class BussinesFactory
{
public static Type BUSSINESS_FACTORY = typeof (NHBussinesFactory);
public static NHBussinesFactory Instance(Type factory)
{
try
{
return (NHBussinesFactory) Activator.CreateInstance(factory);
}
catch (Exception)
{
throw new Exception("No se pudo crear BussinessFactory:"+factory);
}
}
public abstract IRoleController GetRoleController();
public abstract IUserController GetUserController();
public abstract IUserRoleController GetUserRoleController();
}
}

Nuestros Objetos de Negocios: Para nuestro Ejemplo User, UserEntity

image

Interfaz: IUserController

using NHEntity;

namespace NHBussines.Interfaces
{
public interface IUserController : IGenericController<UserEntity, int>
{

}
}

Clase de Negocio: UserController:

using NHBussines.Interfaces;
using NHEntity;

namespace NHBussines.Implementations
{
public class UserController : GenericController<UserEntity, int>, IUserController
{
public UserController()
{
GenericDao = DaoFactory.GetUserDAO();
}
}
}

Así nuestra Factoria de Objetos de Negocios, funciona con el intellisense de Visual Studio:

image

Asi Accedemos a los metodos comunes de nuestra entidad:

image

Espero les haya ayudado con este aporte.

Muchas Gracias.

Jose Fabricio Rojas

Post Similares:
[1] Aplicando Patrones de Diseño a una aplicacion que utiliza NH
[2] Persistencia en .NET