Hola de nuevo,

Creo haber dado con un modelo de diseño que me va bien para mi
aplicación.
He llegado a él usando el container Windsor de Castle Project, he
hecho unas pruebas y parece que todo "me" cuadra.

Para las pruebas he creado una solución, pongamos que se llama
"MiAplicacion", en la aplicación tengo dos formularios, uno para
visualizar, editar, modificar y eliminar (CRUD) cualquier entidad
(usando Generics) y otro especifico que trabaja con Animales y
Personas usando un negocio especifico.

Os enseño la estructura, será más facil de entender así. He intentado
aplicar lo que he aprendido viendo las VAN de Alt.net-hispano durante
estos días.
Me lo he organizado de la siguiente forma:

MiAplicacion (Solución)
    MiAplicacion.Dominio (Mis entidades)
        Animal.cs
        Persona.cs
        Entidad.cs (Base para animal y persona)
    MiAplicacion.Dominio.Impl (Los mappings de mis entidades en NH)
        Animal.hbm.xml
        Animal.hbm.xml
    MiAplicacion.Datos (Interfaces de acceso a datos)
        IDaoGenerico.cs
    MiAplicacion.Datos.Impl (Implementacion de acceso a datos con NH)
        DaoGenerico.cs
    MiAplicacion.Servicio (*)
        Negocio (Carpeta de proyecto)
            IPersonasAnimalesNegocio.cs (Negocio especifico para
animales y personas)
        Controlador (Carpeta de proyecto)
            ICRUDGenericoControlador.cs (Controlador para un
formulario CRUD)
            IPersonasAnimalesControlador.cs (Controlador específico)
    MiAplicacion.Servicio.Impl (*)
        Negocio (Carpeta)
            PersonasAnimalesNegocio.cs (Implementacion de
PersonasAnimalesNegocio)
        Controlador (Carpeta)
            CRUDGenericoControlador.cs (Implementación de
ICRUDGenericoControlador)
            PersonasAnimalesControlador.cs (Implementacion de
IPersonasAnimalesControlador)
    MiAplicacion.WinForm (Winform Application)
        CRUDGenericoForm.cs (Formulario genérico CRUD)
        PersonasAnimalesForm.cs (Formulario específico)

Bien, el proyecto "MiAplicacion.Servicio" y su implementación lo he
marcado con (*) debido a que creo que he hecho algo poco ortodoxo, en
"Servicio" tengo la intención de meter las clases e interfaces de
negocio y los controladores de las vistas, he pensado en ponerlos
juntos porque en cierto modo ambos tienen algo de negocio.

Mi idea es usar Vista Controlador para las interfaces por que las
interfaces no las hago yo, las hace un diseñador, por lo tanto de
arriba hacia abajo e intentado seguir el orden: Vista (WinForm),
Controlador, Negocio, Dao.
Lo curioso que me ha pasado es que al implementar el controlador del
CRUD Genérico me he dado cuenta de que no había negocio, no se como lo
veis vosotros, pero yo en un formulario que muestra una lista de
animales, en el que puedes editar, borrar y modificar no veo negocio
especifico, así pues lo que he hecho ha sido que en
"CRUDGenericoControlador" no he usado una clase de negocio, sino que
directamente uso el DaoGenerico para persistir y leer los datos. Esto
me ha abierto dos escenarios distintos, procesos que tienen un negocio
especifico donde podemos usar distintos Dao para obtener datos de
distintas entidades e interactuar con ellas y procesos tan triviales
en los que no existe un negocio especifico en los cuales solo se
trabaja con una entidad, por lo tanto me ahorro pasar por un
"NegocioGenerico" que solo haga de wrapper al Dao.

¿Que opinais sobre esto? ¿Lo veis aceptable?

Bien, tanto en "DaoGenerico" como en "CRUDGenerico" como en
"CrudGenericoForm" he usado generics, por lo tanto pueden trabajar con
cualquier entidad, lo que me ha maravillado de Castle Windsor ha sido
que me he definido objetos para la vista, el controlador y el dao y me
ha funcionado perfectamente usando generics, en Spring.Net no lo
conseguí (aunque no soy un experto) de esta forma defino los objetos
así:

      <component id="DaoGenerico"
service="MiAplicacion.Datos.IDaoGenerico`1, Data"
type="MiAplicacion.Datos.Impl.GenericoDao`1, MiAplicacion.Datos.Impl">
      </component>
      <component id="CRUDGenericoControlador"
service="MiAplicacion.Servicio.Controlador.ICRUDGenericoControlador`1,
MiAplicacion.Servicio"
type="MiAplicacion.Servicio.Impl.Controlador.CRUDGenericoControlador`1,
MiAplicacion.Servicio.Impl">
        <parameter>
          <dao>${DaoGenerico}</dao>
        </parameter>
      </component>
      <component id="CRUDGenericoForm"
service="MiAplicacion.WinForm.CRUDGenericoForm`1,
MiAplicacion.WinForm" type="MiAplicacion.WinForm.CRUDGenericoForm`1,
MiAplicacion.Winform">
        <parameter>
          <controlador>${CRUDGenericoControlador}</controlador>
        </parameter>
      </component>


Y lo mejor es que para instanciar el form generico para editar
animales puedo hacer esto:

var FormularioCRUDAnimales =
windsorContainer.Resolve<CRUDGenericoForm<Animales>>();

Bien, una vez metido en Windsor he usado la Facility
NHibernateIntegration y las transacciones automáticas de Windsor
(usando atributos).

Ahora tanto en mis controladores como en mis clases de negocio puedo
hacer uso de la sesión NH con el SessionManager de Castle y de las
transacciones con los atributos, si no me equivoco con esto tengo una
sesión por petición (session per request creo que se llama) por lo
tanto lo que tengo que controlar es que cuando esté trajando con datos
en pantalla, dichos datos están fuera de cualquier sesión así que
podría tener problemas con el lazy load y demás. Pero, "si no me
equivoco", bastaría con asociar las entidades a una nueva sesión antes
de trabajar con ellas.

¿Me equivoco?

Ya se que esta no es la lista de "Ayuda a "tolemaC"", y que quizás de
mucho la tabarra, si me paso preguntando sentiros libres en decirmelo,
lo aceptaré de buen grado.

Un saludo,

-- 
Para escribir al Grupo, hágalo a esta dirección: 
[email protected]
Para más, visite: http://groups.google.com/group/NHibernate-Hispano

Responder a