Es posible escribir un repositorio que tenga operaciones CRUD predeterminadas. Por ejemplo:
public interface IRepository<TEntity>
{
TEntity FindByIdentity(object identity);
TEntity FindBy(Expression<Func<TEntity, bool>> specification);
IList<TEntity> FindAll();
IList<TEntity> FindAllBy(Expression<Func<TEntity, bool>> specification);
TEntity Save(TEntity saveable);
void Delete(TEntity deletable);
}
expresión> es básicamente Especificación y consultas se pueden encapsular de ese modo. Si tenemos ese tipo de Repositorio entonces no necesitamos escribir muchos repositorios específicos.
La ruta alternativa es create Query object. Podríamos agregar la interfaz de esa consulta a la capa de Core/Busines Logic y la implementación a la capa Servicios/Datos. De esta forma, tenemos consultas bien nombradas como AllPreferredCustomersQuery. Es bastante similar a las especificaciones, pero las especificaciones no usan infraestructura y, por lo tanto, podemos agregarlo a la capa de Core/Business Logic. Query objetos son más configurables (por ejemplo, es posible agregar límites, estrategias de búsqueda, combinaciones, etc.)
Dos publicaciones útiles sobre el tema: por [Jimmy Bogard] (http://www.lostechies.com/blogs/jimmy_bogard /archive/2009/09/02/ddd-repository-implementation-patterns.aspx) y por [Greg Young] (http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the- generic-repository.aspx). Me inclino por un enfoque híbrido: repositorios genéricos para acciones simples y objetos de consulta para los más complicados. Por lo general, no expongo repositorios a lo que sea que esté utilizando mi lógica (UI, servicio), pero ofrezco funcionalidad en un patrón similar al de servicio/fachada, por lo que el enfoque dual no está expuesto fuera de esta capa de fachada. – tijmenvdk