¿Los Patrones de Unidad de Trabajo y Repositorio son muy útiles para grandes proyectos?


Estoy comenzando un nuevo proyecto web usando ASP.NET Formularios web + EF4. Estoy tratando de aplicar un patrón de repositorio con un patrón de unidad de trabajo siguiendo este tutorial : http://www.dotnetage.com/publishing/home/2011/07/05/6883/the-repository-pattern-with-ef-code-first-dependeny-injection-in-asp-net-mvc3.html

Creo que tengo la idea, pero mi pregunta es que cuando creo un nuevo objeto en el modelo, ¿también tengo que definir ese objeto en IDALContext de la Unidad De Trabajo? ¿No es eso ¿un handbreak para un rápido desarrollo? Además, si trabajas con varios desarrolladores y no quieres que otros desarrolladores vean tu DAL, ¿cómo puedes gestionar esto? Porque en este patrón, según entiendo, cuando creas un nuevo objeto en el modelo también tienes que definirlo en el IDALContext para este tutorial. Siento estar tan confundida por esto.

Author: wonea, 2011-10-29

4 answers

Martin Fowler describe el rol del repositorio como: "Un Repositorio media entre las capas de mapeo de dominio y datos, actuando como una colección de objetos de dominio en memoria". Lo que Entity Framework 4.1 expone es un repositorio en ese sentido. También EF tiene una unidad de trabajo incorporada. Así que mi consejo es ignorar el artículo del blog que mencionaste en tu pregunta.

Código como este no solo es inútil o inútil, sino peligroso porque no hay ningún beneficio añadido a su código, sino un la dependencia!

public interface IUnitOfWork:IDisposable
{
    int SaveChanges();
}

public interface IDALContext : IUnitOfWork
{
    ICategoryRepository Categories { get; }
    IProductRepository Products { get; }
}

Para responder a su pregunta, tener algo de abstracción que media entre las capas de mapeo de dominio y datos, actuar como una colección de objetos de dominio en memoria es una necesidad para proyectos "grandes". Y tener un mecanismo de UnitOfWork debajo del capó puede ayudar a desacoplar su lógica de negocio del acceso a una cierta abstracción de acceso a datos.

TL; TR; Repository y UnitOfWork pueden ayudarte, pero no lo apliques como en la entrada de blog dada.

 18
Author: saintedlama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-29 19:12:00

Ahora, la primera pregunta debería ser, ¿por qué necesito un repositorio o unidad de patrón de trabajo en absoluto? ¿No podría simplemente usar el contexto EF desde el controlador, teniendo todo el poder de escribir directamente la consulta que necesito y devolver los datos?
Respuesta: Podrías, pero la intención real detrás es la capacidad de prueba y, por lo tanto, un código de mayor calidad y más mantenible. Si separa el acceso a los datos y lo concentra en un solo lugar, puede simularlo durante las pruebas. Esto le permite unit pruebe la lógica definida dentro de su controlador sin escribir efectivamente en un almacén de datos.

Antes de comenzar con la Unidad de Trabajo, simplemente use echar un vistazo al patrón de repositorio . Esto básicamente abstrae el acceso a los datos de una entidad dada. Así que defines métodos como Filter (), All (), Update (..), Insertar(..), Eliminar(...) y finalmente, Save (). En realidad, la mayoría de estos podrían ser fácilmente abstraídos a una clase BaseRepository<TEntity> tal que al final solo tendría que cree un nuevo repositorio en casos raros con un comportamiento especial. De lo contrario sería algo como BaseRepository<Person> personRepo = new BaseRepository<Person>() o BaseRepository<Address> addressRepo = new BaseRepository<Address>() etc.

¿Por qué se necesita la Unidad de Trabajo?
Una unidad de trabajo representa todas las operaciones realizadas durante un ciclo determinado, en un entorno web normalmente por solicitud Http. Esto significa que cuando entra una nueva solicitud, instanciasuna nueva Unidad de Trabajo, agregas cosas nuevas, las actualizas o las eliminas y luego "confirmas" los cambios invocando .save()o .commit()..Lo que sea. En realidad si eche un vistazo más de cerca a Entity Framework DbContext (o ObjectContext), ya están representando algún tipo de Unidad de Trabajo.
Sin embargo, si desea abstraerlo aún más, porque no necesariamente le gustaría tener su contexto EF en sus clases de controlador (recuerde: testability), cree un UoW para agrupar sus repositorios y también para asegurarse de que todos compartan la misma instancia de contexto EF. Puede lograr esto último también a través de un contenedor DI (Inyección de dependencia contenedor).

A sus preguntas: ¿Es útil en grandes proyectos?:
Definitivamente, especialmente en grandes proyectos. Se trata de mantener las responsabilidades separadas (acceso a datos, lógica de negocios, lógica de dominio) y, por lo tanto, hacer que las cosas sean comprobables.

 93
Author: Juri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-11 07:51:23

Los patrones de diseño de software están diseñados para resolver problemas específicos con el contexto correcto, y si se usan de manera inapropiada, conducirán a una complejidad adicional innecesaria sin proporcionar ningún valor.

Entonces, ¿cuáles son los problemas que el patrón de repositorio pretende resolver?

1- Minimizando la lógica de consulta duplicada: en aplicaciones grandes, puede encontrar muchas consultas LINQ complejas duplicadas en algunos lugares. Si ese es el caso, puede usar el patrón de repositorio para encapsule estas consultas y minimice la duplicación.

2- Mejor separación de preocupaciones: Imagine una consulta compleja para obtener los cursos más vendidos en una categoría dada que implica carga ansiosa, unión, agrupación, filtrado, etc.

Cuando implemente consultas tan grandes y complejas en sus servicios/controladores, terminará con servicios/controladores fat. Estas clases se vuelven difíciles de probar por unidad, ya que requerirán mucho stubbing ruidoso. Sus pruebas unitarias se vuelven largas, gordas, e inalcanzable.

Si se enfrenta a este problema, tal vez podría considerar el uso del patrón de repositorio. En este ejemplo, podemos encapsular la consulta compleja para obtener los cursos más vendidos en un repositorio:

courseRepository.GetTopSellingCourses(int categoryId, int count);

De esta manera, sus servicios/controlador ya no se ocuparán de la carga ansiosa, la unión, la agrupación, etc. En su lugar, delegarán en el repositorio. Recuerde, la carga ansiosa, la unión y la agrupación, etc. están consultando la lógica y pertenece a su capa de acceso a datos, no a su servicios o capa de presentación.

3- Desacoplar la arquitectura de su aplicación de persistence frameworks: cuando usa clases de Entity Framework (por ejemplo, DbContext, DbSet, etc.) directamente en su aplicación, su aplicación está estrechamente acoplada a Entity Framework. Si planea cambiar a un O/RM diferente en algún momento en el futuro, o incluso una versión más reciente de Entity Framework con un modelo diferente, es posible que tenga que modificar muchas partes de su aplicación y esto puede conducir a nuevos errores en su solicitud. Puede usar el patrón de repositorio para desacoplar la arquitectura de la aplicación de marcos de persistencia como Entity Framework. De esta manera, tendrá la libertad de cambiar a un O/RM diferente con un impacto mínimo en su aplicación.

Echa un vistazo a este video para más detalles:

Https://youtu.be/rtXpYpZdOzM

 1
Author: Mosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-20 07:56:42

Debe considerar "objetos de comando / consulta" como una alternativa, puede encontrar un montón de artículos interesantes alrededor de esta área, pero aquí hay uno bueno:

Https://rob.conery.io/2014/03/03/repositories-and-unitofwork-are-not-a-good-idea /

Se adhería a un único objeto de comando por comando para permitir transacciones simples, evitando la necesidad de la complejidad de la Unidad de patrón de Trabajo.

Sin embargo, si está pensando que un objeto de consulta por consulta es overkill, podrías estar 100% en lo cierto. A menudo puede elegir comenzar con un objeto' FooQueries', que es esencialmente un Repositorio pero solo para Consultas. 'Foo' podría ser tu 'agregado de dominio' en el sentido DDD.

Puede encontrar objetos de consulta individuales que valgan la pena más adelante.

Al igual que con la mayoría de las cosas, debe considerar sistema por sistema.

 0
Author: Darren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-12 01:39:22