you are welcome El 21 de enero de 2010 14:48, Edgar Ramos <[email protected]> escribió:
> Gracias Fabio > > En un curso me dijeron lo siguiente, no porque la herramienta te > permite hacer tal cosa, quiere decir que sea correcto... > Las preguntas que me planteas, son las mismas que en su momento mes > las hice y por medio de googlear me llevaron a nhibernate y a este > foro, hoy con los proyectos nuevos que tengo, estoy tratando de hacer > las cosas bien, es decir siguiendo metodologias, patrones de diseño y > aprendiendo a utilizar framework (nh, castle, etc) e investigando > claro esta > > nuevamente gracias por todo > > > > El día 21 de enero de 2010 11:19, Fabio Maulo <[email protected]> > escribió: > > bueno... si eso significa "un solo paso" y eso eso lo que te gusta seguí > los > > links que mandó Angel (AJL) ya que son para trabajar con > StoredProcedures. > > En este foro, es probable, que vas a encontrar poca ayuda sobre como > > trabajar con NH+SP exactamente porque quien trabaja con ORM trata de > evitar > > meter logica de negocio en las SPs. > > Te hago otras preguntas: > > Como estas probando que esas SPs hacen exactamente lo que tienen que > hacer ? > > Tenes un programa o algo "computerizado" que pruebe que cada SP se "porte > > bien" ? > > Si te piden de cambiar RDBMS contestá "no se puede", te pegas un tiro, o > le > > facturas un fangote ? > > Cuanto programadores C# tenes y cuanto programadores de SPs tenes ? > > Cuanto te sale un programador C# y cuanto te sale un programador de SPs > ? > > Que seguridad te da una SP que no te de un metodo de una clase ? > > Es mas rapido escribir una SP o uno o n metodos de clases C# ? > > Si mucha logica de negocio se ejecuta en la misma PC donde está el DB, > > cuanto escalable es tu applicación ? > > Cuanto cuesta agregar potencia de procesamiento a un server-DB y cuanto > > cuesta agregar un WEB-server ? > > Tengo otras, pero con estas creo que tenes para pensar un rato. > > > > El 21 de enero de 2010 11:51, Edgar Ramos <[email protected]> > escribió: > >> > >> Gracias a todos, se lee la ciencia, incribirme en este foro ha sido lo > >> mejor que hecho > >> > >> Bueno vamos por partes > >> > >> Fabio, de un solo paso, en resumen, mando a mi store procedure los > >> parametros necesarios y este internamente manejando transacciones, > >> actualiza, elimina, inserta en fin hace varias cosas, un ejemplo > >> seria, trabajo en un hotel , el cliente hace check-out, cancelo su > >> folio (cuenta), actualizo el estado del huesped a "huesped salio", > >> actualizo el estado de la habitacion a "habitacion sucia", en fin > >> varias cosas realacionadas en un solo store procedure > >> > >> Carlos y Jose, mil gracias por compartir sus conocimientos, si > >> efectivamente soy nuevo, pero que eso no les detenga, quiero ser bueno > >> asi que tengo que aprender de los buenos, si hay que leer, investigar, > >> lo hago con mucha ganas, durante mi vida he desarrollado software de > >> forma estructurada, el paso a POO, me ha costado pero sigo en la > >> lucha, pero no desmayo > >> > >> al leer sus posts, tengo la pauta de ir a consultar en internet mas > >> sobre estos temas, por ejemplo DDD, DomainEvent, patrones de diseño, > >> GRASP, etc > >> > >> gracias nuevamente > >> > >> > >> > >> El día 21 de enero de 2010 06:23, José F. Romaniello > >> <[email protected]> escribió: > >> > Si, ahora me di cuenta y tenes razón. Perdón si parece abrumadora la > >> > otra > >> > explicación > >> > > >> > El 21 de enero de 2010 07:54, Carlos Peix <[email protected]> > >> > escribió: > >> >> > >> >> Hola Jose, > >> >> Estoy de acuerdo con vos, solo me gustaria que releas el primer post > de > >> >> Edgar. > >> >> Puedo equivocarme pero entendi que el recien esta empezando con este > >> >> tipo > >> >> de diseño y juzgue que proponer un patron visitor lo asustaria o le > >> >> haria > >> >> mas dificil un primer paso. Mucho menos se me ocurriria apuntarlo al > >> >> blog de > >> >> Udi (con el cual estoy de acuerdo, sobre todo con DomainEvents). > >> >> Entiendo que para la mayoria de la audiencia de esta lista mi > propuesta > >> >> parece juego de niños pero vale la pena, ya veran cuando dentro de un > >> >> par de > >> >> años Edgar nos solucione los problemas a nosotros o a otros :-). > >> >> De todas maneras esta bueno que tenga alternativas para elegir. > >> >> Un abrazo > >> >> ---------------------------------- > >> >> Carlos Peix > >> >> > >> >> 2010/1/21 José F. Romaniello <[email protected]> > >> >>> > >> >>> No me gusta esta arquitectura Carlos. > >> >>> Para mi el servicio que lleva a cabo el caso de uso de dar de alta > una > >> >>> venta tiene que terminar grabando una venta con su repositorio. Tal > >> >>> vez el > >> >>> movimiento de stock, es un agregado de la misma venta, pero para > este > >> >>> caso > >> >>> voy a suponer que no. > >> >>> Hace un tiempo escribí sobre un dominio "parecido" ;) > >> >>> > >> >>> > >> >>> > http://jfromaniello.blogspot.com/2009/11/caso-practico-patron-visitor.html > >> >>> > >> >>> Mi idea es que e > >> >>> public class RegistroDeVentas > >> >>> { > >> >>> IVisitor<Venta> visitors; > >> >>> public RegistroDeVentas(IVisitor<Venta>...visitors, > >> >>> IRepositorioVenta > >> >>> repVenta) { > >> >>> } > >> >>> public RegistrarVenta(Venta venta) > >> >>> { > >> >>> foreach (var visitor in visitors) > >> >>> { > >> >>> if(visitor.EsAplicable(venta)) > >> >>> visitor.Aplicar(venta) > >> >>> } > >> >>> repVenta.Guardar(venta) > >> >>> } > >> >>> } > >> >>> La interfaz IVisitor tiene solo esos dos metodos que aparecen ahí, > en > >> >>> la > >> >>> configuración del container digo que visitors se aplican para este > use > >> >>> case. > >> >>> Un ejemplo de visitor para Movimiento Stock sería > >> >>> public class AplicadorDeStockPorVentas : IVisitor<Venta> > >> >>> { > >> >>> public AplicadorDeStockPorVentas(IRepositorioStock repStock){ > >> >>> repStock = ...} > >> >>> public bool EsAplicable(Venta venta) > >> >>> { > >> >>> return venta.TipoDeVenta.MueveStockFisico && > >> >>> venta.EntregaInmediata > >> >>> } > >> >>> public void Aplicar(Venta venta) > >> >>> { > >> >>> foreach(var linea in venta.Lineas) > >> >>> { > >> >>> var movStock = new MovimientoStock(linea.Articulo, > >> >>> linea.Cantidad, Signo.Debito); > >> >>> repStock.Guardar(movStock); > >> >>> } > >> >>> } > >> >>> } > >> >>> Me encanta este tipo de código por que es muy facil testearlo. > >> >>> Si bien en su momento estaba convencido ahora me copa mas la idea de > >> >>> DomainEvents, igual, el código me queda muy similar. > >> >>> Yo uso la misma implementación de Udi, solamente que con > >> >>> ServiceLocator, > >> >>> y en vez de ser todo estática la clase DomainEvents, tengo un > >> >>> IDomainEvents > >> >>> (o IDomainEventsManager el cual inyecto en los servicios) > >> >>> http://www.udidahan.com/2009/06/14/domain-events-salvation/ > >> >>> > >> >>> El 21 de enero de 2010 00:13, Carlos Peix <[email protected]> > >> >>> escribió: > >> >>>> > >> >>>> Hola Edgard, > >> >>>> Creo que deberias mirar codigo escrito por otros para tener una > >> >>>> vision > >> >>>> global. Aunque no adhiero 100% a los detalles de esta arquitectura, > >> >>>> podrias > >> >>>> mirar esto: http://code.google.com/p/sharp-architecture/ > >> >>>> No obstante, te dejo aqui algo esquematico (no me critiquen por > >> >>>> favor, > >> >>>> abajo aclaro como profesionalizar este codigo :-) ). > >> >>>> Supongamos que tenes una clase que representa la venta: > >> >>>> public class Venta { > >> >>>> IList<LineaVenta> lineas; > >> >>>> } > >> >>>> y otra que representa a un movimiento de stock > >> >>>> public class MovimientoStock { > >> >>>> IList<LineaMovimientoStock> lineas; > >> >>>> } > >> >>>> Luego se me ocurre una suerte de servicio o de componente cuya > >> >>>> responsabilidad sea aplicar la venta contra el stock: > >> >>>> public class AplicadorDeVentaAStock { > >> >>>> public MovimientoStock AplicarVenta(Venta venta) { > >> >>>> // aqui va la logica por la cual se aplica la venta y se CREA > >> >>>> // un objeto MovimientoStock > >> >>>> return movimientoStock; > >> >>>> } > >> >>>> } > >> >>>> Como veras, hasta aqui no hay nada de persistencia, solo logica de > >> >>>> negocio. > >> >>>> Veamos ahora como interviene la persistencia: seguramente un > usuario > >> >>>> presionara un boton cuando quiere grabar la venta, en el codigo de > >> >>>> ese boton > >> >>>> deberia llamarse a un objeto (un servicio o fachada de aplicacion) > >> >>>> cuya > >> >>>> responsabilidad sea registrar la venta: > >> >>>> public class RegistroDeVentas { > >> >>>> public void Registrar(Venta venta) { > >> >>>> MovimientoStock movimientoStock > >> >>>> = aplicadorDeVentaAStock.AplicarVenta(venta); > >> >>>> repositorioVenta.Save(venta); > >> >>>> repositorioMovimientoStock.Save(movimientoStock); > >> >>>> } > >> >>>> } > >> >>>> Es sencillo no? la version real no tiene que ser mas compleja pero > >> >>>> creo > >> >>>> que es necesario dar algunas pautas y aclaraciones. > >> >>>> De donde salen aplicadorDeVentaAStock, repositorioVenta > >> >>>> y repositorioMovimientoStock en el metodo Registrar? es aqui donde > >> >>>> aparece > >> >>>> injeccion de dependencias o DI, no voy a configurar todo eso pero > si > >> >>>> voy a > >> >>>> sugerir el contructor de la clase RegistroDeVentas: > >> >>>> public class RegistroDeVentas { > >> >>>> IAplicadorDeVentaAStock aplicadorDeVentaAStock; > >> >>>> IRepositorioVenta repositorioVenta; > >> >>>> IRepositorioMovimientoStock repositorioVenta; > >> >>>> > >> >>>> > >> >>>> > public RegistroDeVentas(IAplicadorDeVentaAStock aplicadorDeVentaAStock, > >> >>>> IRepositorioVenta > >> >>>> repositorioVenta, > >> >>>> > >> >>>> IRepositorioMovimientoStock repositorioVenta) { > >> >>>> this.aplicadorDeVentaAStock = aplicadorDeVentaAStock; > >> >>>> this.repositorioVenta = repositorioVenta; > >> >>>> this.repositorioMovimientoStock = repositorioMovimientoStock; > >> >>>> } > >> >>>> } > >> >>>> Estas instancias seran "injectadas" en esta fachada de servicio por > >> >>>> un > >> >>>> container, por ejemplo, Windsor. > >> >>>> Alguno que todavia este despierto notara que use el > >> >>>> tipo IAplicadorDeVentaAStock para el aplicador de stock, esto nos > >> >>>> permitira, > >> >>>> dependiendo de las preferencias de nuestro cliente, utilizar > >> >>>> distintas > >> >>>> estrategias de aplicacion de stock. Esto es el patron Strategy. > >> >>>> Por supuesto que tambien debe iniciarse transacciones asociadas a > los > >> >>>> repositorios, tambien puede hacerse mediante configuracion. > >> >>>> Creo que con este esquemas tenes algo sencillo que puede servir > para > >> >>>> aclararte el panorama al tiempo que, con las aclaraciones que > agregue > >> >>>> mas un > >> >>>> poco de investigacion de tu parte llegar a algo bastante > profecional, > >> >>>> extensible y testeable. > >> >>>> Un saludo. > >> >>>> PD: Pierde Boca, gana River :-( > >> >>>> ---------------------------------- > >> >>>> Carlos Peix > >> >>>> > >> >>>> 2010/1/20 Edgar Ramos <[email protected]> > >> >>>>> > >> >>>>> Gracias por los comentarios, antes manejaba toda esta logica con > >> >>>>> store > >> >>>>> procedures y triggers, hoy requiero hacerlo de la forma correcta, > >> >>>>> Carlos tu punto de vista me ha quedado gustando, algun link donde > >> >>>>> profundizar seria bienvenido > >> >>>>> > >> >>>>> > >> >>>>> saludos > >> >>>>> > >> >>>>> El día 20 de enero de 2010 15:46, Carlos Peix > >> >>>>> <[email protected]> > >> >>>>> escribió: > >> >>>>> > Diego, > >> >>>>> > Para que veas que soy un caballero: yo no disiento con vos. :-) > >> >>>>> > Por supuesto que Diego tiene razon pero, conceptualmente, lo que > >> >>>>> > señala es > >> >>>>> > el equivalente a un store procedure (mas precisamente un > trigger) > >> >>>>> > escrito en > >> >>>>> > C#. > >> >>>>> > Puede funcionar pero no es recomendable en un diseño nuevo, > desde > >> >>>>> > cero. Al > >> >>>>> > menos en mi opinion. > >> >>>>> > ---------------------------------- > >> >>>>> > Carlos Peix > >> >>>>> > > >> >>>>> > 2010/1/20 Diego Mijelshon <[email protected]> > >> >>>>> >> > >> >>>>> >> Disiento con Carlos respecto de si es _posible_ hacer esto, > >> >>>>> >> aunque > >> >>>>> >> estoy > >> >>>>> >> de acuerdo en que no es un muy buen diseño. > >> >>>>> >> Para lograr algo así, podrías usar un PostInsertEventListener > que > >> >>>>> >> haga la > >> >>>>> >> actualización. > >> >>>>> >> Algo más o menos así (no testeado): > >> >>>>> >> void OnPostInsert(PostInsertEvent @event) > >> >>>>> >> { > >> >>>>> >> var linea = @event.Entity as Linea; > >> >>>>> >> if (linea != null) > >> >>>>> >> @event.Session.CreateQuery("update Producto set Stock = > Stock > >> >>>>> >> - > >> >>>>> >> :cantidad where Id = :idProducto") > >> >>>>> >> .SetParameter("cantidad", linea.Cantidad) > >> >>>>> >> .SetParameter("idProducto", linea.Producto.Id) > >> >>>>> >> .ExecuteUpdate() > >> >>>>> >> } > >> >>>>> >> Así y todo, estarías usando un event listener, que es una > >> >>>>> >> herramienta de > >> >>>>> >> infraestructura de NHibernate para un concern específico de > >> >>>>> >> negocio, > >> >>>>> >> lo cual > >> >>>>> >> tiene bastante mal olor. > >> >>>>> >> > >> >>>>> >> Diego > >> >>>>> >> > >> >>>>> >> > >> >>>>> >> 2010/1/20 Edgar Ramos <[email protected]> > >> >>>>> >>> > >> >>>>> >>> Saludos a todos > >> >>>>> >>> > >> >>>>> >>> Como ejemplo similar el siguiente > >> >>>>> >>> > >> >>>>> >>> Tengo estas entidades, Venta, Linea (detalle de la venta), y > >> >>>>> >>> Producto > >> >>>>> >>> (con su stock), y requiero hacer lo siguiente > >> >>>>> >>> > >> >>>>> >>> Al momento de crear Una venta e ingresar su Detalle (Linea), > me > >> >>>>> >>> actualice el stock de cada uno de los productos (de Linea), > >> >>>>> >>> basicamente stock=stock-(cantidad digitada) > >> >>>>> >>> > >> >>>>> >>> Puedo hacer esto ? > >> >>>>> >>> > >> >>>>> >>> Cualquier comentario es bienvenido > >> >>>>> >>> > >> >>>>> >>> Gracias nuevamente > >> >>>>> >>> > >> >>>>> >>> -- > >> >>>>> >>> Para escribir al Grupo, hágalo a esta dirección: > >> >>>>> >>> [email protected] > >> >>>>> >>> Para más, visite: > >> >>>>> >>> http://groups.google.com/group/NHibernate-Hispano > >> >>>>> >> > >> >>>>> >> > >> >>>>> >> -- > >> >>>>> >> Para escribir al Grupo, hágalo a esta dirección: > >> >>>>> >> [email protected] > >> >>>>> >> Para más, visite: > >> >>>>> >> http://groups.google.com/group/NHibernate-Hispano > >> >>>>> > > >> >>>>> > > >> >>>>> > -- > >> >>>>> > Para escribir al Grupo, hágalo a esta dirección: > >> >>>>> > [email protected] > >> >>>>> > Para más, visite: > >> >>>>> > http://groups.google.com/group/NHibernate-Hispano > >> >>>>> > > >> >>>>> > >> >>>>> -- > >> >>>>> Para escribir al Grupo, hágalo a esta dirección: > >> >>>>> [email protected] > >> >>>>> Para más, visite: > http://groups.google.com/group/NHibernate-Hispano > >> >>>> > >> >>>> > >> >>>> -- > >> >>>> Para escribir al Grupo, hágalo a esta dirección: > >> >>>> [email protected] > >> >>>> Para más, visite: > http://groups.google.com/group/NHibernate-Hispano > >> >>> > >> >>> > >> >>> -- > >> >>> Para escribir al Grupo, hágalo a esta dirección: > >> >>> [email protected] > >> >>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano > >> >> > >> >> > >> >> -- > >> >> Para escribir al Grupo, hágalo a esta dirección: > >> >> [email protected] > >> >> Para más, visite: http://groups.google.com/group/NHibernate-Hispano > >> > > >> > > >> > -- > >> > Para escribir al Grupo, hágalo a esta dirección: > >> > [email protected] > >> > Para más, visite: http://groups.google.com/group/NHibernate-Hispano > >> > > >> > >> -- > >> Para escribir al Grupo, hágalo a esta dirección: > >> [email protected] > >> Para más, visite: http://groups.google.com/group/NHibernate-Hispano > > > > > > > > -- > > Fabio Maulo > > > > > > -- > > Para escribir al Grupo, hágalo a esta dirección: > > [email protected] > > Para más, visite: http://groups.google.com/group/NHibernate-Hispano > > > > -- > Para escribir al Grupo, hágalo a esta dirección: > [email protected] > Para más, visite: http://groups.google.com/group/NHibernate-Hispano > -- Fabio Maulo
-- Para escribir al Grupo, hágalo a esta dirección: [email protected] Para más, visite: http://groups.google.com/group/NHibernate-Hispano
