Pregunta

Es posible (incluso probable) que no estoy totalmente Grokking el concepto de una "unidad de trabajo". Básicamente, lo veo como una especie de transacción amplio que se utiliza en un entorno orientado a objetos. Comience la unidad de trabajo, interactuar con los objetos, cometer o hacia atrás rollo. Pero ¿cómo funciona este salto hacia abajo a las transacciones reales en los almacenes de datos detrás de esos objetos?

En un sistema con un solo DB y un ORM (como NHibernate) que es fácil. La transacción se puede mantener a través del ORM. Pero ¿qué pasa con un sistema en el que los modelos de dominio personalizados están ocultando muchas fuentes de datos dispares? Y no todas esas fuentes de datos son bases de datos relacionales? (Hay mucho hecho en el sistema de archivos por aquí.)

Ahora estoy atascado en la idea de que "simplemente no se puede mantener una transacción a través de una base de datos SQL2005, un SQL2000 DB, DB2 una base de datos, y el sistema de archivos en la misma operación de negocios 'atómica'." Así que por ahora es la responsabilidad de los desarrolladores en el equipo (que por lo general funciona de forma independiente el uno del otro) para mantener las transacciones manualmente en el código. Cada base de datos puede tener transacciones adecuadas en él, pero la operación del negocio en su conjunto ha sido controlada y equilibrada en cada paso importante de la forma manual.

Sin embargo, con el aumento de la complejidad en la facturación de dominio y desarrollador estándar, este enfoque será cada vez más difícil y propenso a errores en el tiempo.

¿Alguien tiene algún consejo o ejemplos de cómo un dominio como esto podría dirigirse mejor, o la forma en que se ha abordado antes? El "dominio" real en este caso es todavía muy en su infancia, evolucionando como un prototipo a un día de ampliar y consumir / reemplazar un gran ecosistema de aplicaciones heredadas dispares. Así que hay mucho espacio para la re-diseño y re-factorización.

Como referencia, una vista de 10.000 pies del diseño Actualmente estoy apuntando es: Una gran colección de pequeñas como-mudo-como-posible aplicaciones de cliente que llaman a un servicio central basado en mensajes. El servicio es la entrada en el "núcleo de dominio" y se puede considerar como una aplicación de gran estilo MVC. Se hacen peticiones al servicio (muy parecido a "acciones") que son recogidas por los manipuladores (muy parecido a "controladores"). Cualquier cosa procedimiento va allí. Ellos interactúan con los modelos, que contienen todas las reglas de negocio. Los modelos publican sucesos que los oyentes ( "servicios"? Esta parte es aún turbia en el diseño y sujetos a mejoras) recoger y mango al interactuar con los repositorios de base de datos (x, y la base de datos, sistema de archivos, correo electrónico, cualquier recurso externo). Todo alegremente dependencia-inyecta en consecuencia.

Lo siento por todo el nivel de detalle :) Pero si alguien tiene algún consejo, me encantaría escucharlo. Incluso (especialmente) si ese consejo es "el diseño es malo, probar este lugar ..." Gracias!

¿Fue útil?

Solución

previamente trabajó en un sistema que podría lograr esto, y es bastante sencillo. Dado que proyecto se encuentra en sus primeras etapas, tal vez esto podría ser información útil para usted. Por desgracia, ya no tengo acceso al código, pero todavía estoy cómodo en la descripción de cómo funcionaba.

¿Qué había hecho fue construido mis repositorios usando un patrón de aplicación repositorio genérico. El tipo de repositorio de base siempre sería referencias de los servicios y UoW. Por el bien de la discusión, lo llamaremos BaseRepository. "T" se limitaría a las implementaciones IEntity, que denotaban un objeto de dominio. Desde el BaseRepository, que había creado otro conjunto de clases base para la composición, tales como SqlBaseRepository, XmlBaseRepository, etc.

El UoW sólo se preocupa de que algo es del tipo BaseRepository, que es donde existiría la funcionalidad básica. CUD básico (de ABM) estaría representado, proporcionando los equivalentes de Crea, actualizaciones y eliminaciones. Lo que cada uno de ellos haría sería crear un delegado y colocarlo en una cola dentro de la UoW, que pasa también a lo largo de información sobre qué tipo de operación que iba a ser, y los datos apropiados necesarios para su realización. El UoW comenzaría el mantenimiento de una lista de lo que los repositorios se van a necesitar estar involucrado en la transacción, pero aún no le importaba de qué tipo era. Effictively, haciendo cola aquí es como alistarse en una transacción.

El BaseRepository define un método abstracto llamado algo así como .ApplyChange (). Una vez .Commit () fue llamado en el UoW, se crearía una TransactionScope () y empezar a llamar a los delagates en la lista, que pasa de regreso a la información .ApplyChange (). Existe la implementación real de .ApplyChange () en la base repositorio específico, es decir, el SqlRepositoryBase, etc., y podría ser anulado por la aplicación, también.

Cuando se puso difícil, al menos para mí, estaba rodando hacia atrás. Sólo ocupado de una sola base de datos, pero a veces tenía cambios basados ??en archivos que se hicieron. He añadido una .RevertChange () método y estados iniciadas el seguimiento del estado original y modificados de manera que, básicamente, pude aplicar un reverso-delta para volver a donde estaba en la pila de archivos.

Me gustaría que pudiera ser más específico sobre la aplicación, pero ha sido más de un año desde que he visto el código ahora. Te puedo decir que la base para el código original fue llevado desde el libro, .NET de Dominio impulsado Diseño con C #: Problema - Diseño - Solución , por Tim McCarthy. Una gran cantidad de mi implementación del repositorio se basó en sus ejemplos, con una gran mayoría de mi personalización enviado desde la UOWs y su aplicación.

Espero que ayude, algo! : -)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top