1) ¿Qué hacer si desea cambiar los ORM? Tendría un código ORM específico en su aplicación si no lo contiene en un repositorio.
Todavía no he estado en una posición donde la compañía, de repente, decidió cambiar la tecnología de acceso a datos. Si esto sucede, se requerirá algo de trabajo. Tiendo a abstraer las operaciones de acceso a datos a través de interfaces. El repositorio es una forma de resolver esto.
Entonces tendría un ensamblaje diferente para la implementación concreta de mi capa de acceso a datos. Por ejemplo, podría tener:
Company.Product.Data
y Company.Product.Data.EntityFramework
asambleas. El primer ensamblado se usaría exclusivamente para interfaces, cuando otro sería una implementación concreta de la lógica de acceso a datos de Entity Framework.
2) ¿Sigue siendo válido el patrón de repositorio cuando no está utilizando un ORM y está utilizando ADO.net para acceder a los datos y completar los datos del objeto usted mismo?
Creo que depende de usted decidir qué patrón es válido o no. He usado un patrón de repositorio en la capa de presentación. Una cosa a tener en cuenta es que a las personas les gusta poner responsabilidades en los repositorios. Antes de que te des cuenta, tu clase de repositorio será bailar, cantar y hacer todo tipo de cosas. Quieres evitar esto.
He visto una clase de repositorio que comenzó teniendo las responsabilidades GetAll, GetById, Update y Delete, lo cual está bien. Para cuando se completó el proyecto, esa misma clase tenía docenas de métodos (responsabilidades) que nunca deberían haber estado allí. Por ejemplo, GetByForename, GetBySurname, UpdateWithExclusions y todo tipo de cosas locas.
Aquí es donde entran en juego las consultas y los comandos.
3) Si usa un ORM pero no el patrón de repositorio, ¿dónde guarda las consultas de uso común? ¿Sería prudente representar cada consulta como una clase y tener algún tipo de fábrica de consultas para crear instancias?
Creo que es una muy buena idea tener consultas y comandos de uso en lugar de repositorios. Hago lo siguiente:
Definir interfaz para una consulta. Esto lo ayudará a realizar pruebas unitarias. P.ejpublic interface IGetProductsByCategoryQuery { ... }
Definir implementación concreta para una consulta. Podrá inyectarlos a través del marco de IoC que elija. P.ejpublic class GetProductsByCategoryQuery : IGetProductsByCategoryQuery
Ahora, en lugar de contaminar el repositorio con docenas de responsabilidades, simplemente agrupo mis consultas en espacios de nombres. Por ejemplo, una interfaz para la consulta anterior puede vivir: Company.SolutionName.Products.Queries
y la implementación puede vivir enCompany.SolutionName.Products.Queries.Implementation
Cuando se trata de actualizar o eliminar datos, uso el patrón de comando de la misma manera.
Algunos podrían estar en desacuerdo y decir que antes de que se complete el proyecto, tendrá docenas de clases y espacios de nombres. Sí lo harás. En mi opinión, es bueno, ya que puede navegar a través de la solución en IDE de su elección y ver instantáneamente qué tipo de responsabilidades tiene cierto componente. Si ha decidido utilizar un patrón de repositorio en su lugar, tendrá que mirar dentro de cada clase de repositorio tratando de resolver sus responsabilidades.