¿Es este un uso adecuado de DTO?

Estoy escribiendo una aplicación de consola que realiza una buena cantidad de recuperación de datos de los conjuntos de registros de procedimientos almacenados. Para cada tipo de conjunto de registros con el que estoy trabajando, tengo un Repositorio que usa EF con tipos complejos personalizados para recuperar los datos:

public interface IBalanceSheetRepository { IEnumerable GetBalanceSheetRecords(); } public class BalanceSheetRepository : IBalanceSheetRepository { DBContext _context; ... public IEnumerable GetBalanceSheetRecords() { ObjectResult results = _context.GetBalanceSheet(); return results.Select(CreateBalanceSheetDTOFromDAO); } private static BalanceSheetRecordDTO CreateBalanceSheetDTOFromDAO(BalanceSheetRecord dao) { return new BalanceSheetRecordDTO { ... }; } } 

Aquí, BalanceSheetRecord es un tipo de datos complejo que creé en el diseñador. Creé un DTO para evitar el acoplamiento, ya que el BLL no debería saber sobre el tipo BalanceSheetRecord .

Aquí está mi pregunta: dado que el tipo DTO se usa en la firma del método de la interfaz del repository, y dado que mi BLL finalmente usará el repository y se devolverá una colección de los DTO, parece ser una preocupación transversal. Por lo tanto, tengo el DTO viviendo en un conjunto de “Infraestructura” por separado, junto con las interfaces de repository. ¿Es esta buena práctica para lo que estoy tratando de lograr, o tomé un giro equivocado en alguna parte?

También: ¿Es una mala práctica actualizar el contexto de datos en mi repository? ¿Alguna cantidad de acoplamiento está bien cuando ambos componentes pertenecen al DAL? Quiero usar DI pero parece más útil para intercambiar la implementación DBContext del repository para un TestBalanceSheetRepository , por ejemplo.

Prefiero devolver entidades reales desde mis repositorys. De esta manera, cuando necesita organizar interacciones complejas entre diferentes entidades en la capa de servicio, no hay conversión hacia adelante y hacia atrás a DTO. La capa de servicio luego proyecta entidades en DTO cuando se devuelven datos a la capa de aplicación.

Sé que hay puristas que dicen que todas las interacciones entre capas deben realizarse con DTO, pero eso no es práctico. La capa de servicio terminará acoplada a las entidades de todos modos, por lo que no es como si estuvieras agregando acoplamiento.

También limita la proyección / aplanamiento de DTO a las entidades a la capa de servicio. Lo que para mí es una ventaja, ya que estas actividades aumentan la complejidad y disminuyen el rendimiento.

Su contexto de datos es su unidad de trabajo. La idea de “una unidad de trabajo por repository” es un anti-patrón. Las unidades de trabajo deben estar en el ámbito de la capa de servicio, que puede incluir 1-muchas entidades de 1-muchos repositorys. Si cada repository tiene una unidad de trabajo diferente, perderá su capacidad de hacer que las llamadas de la capa de servicio mantengan transacciones consistentes con facilidad.