1) Cosa fare se si desidera cambiare ORM, si avrebbe un codice ORM specifico nella propria applicazione se non lo si contiene in un repository.
Non sono ancora stato in una posizione in cui all'improvviso un'azienda ha deciso di cambiare tecnologia di accesso ai dati. Se ciò accade, sarà necessario un po 'di lavoro. Tendo ad astrarre le operazioni di accesso ai dati attraverso le interfacce. Il repository è un modo per risolverlo.
Avrei quindi un assemblaggio diverso per l'implementazione concreta del mio livello di accesso ai dati. Ad esempio, potrei avere:
Company.Product.Data
e Company.Product.Data.EntityFramework
assemblee. Il primo assembly verrebbe utilizzato esclusivamente per le interfacce, mentre un altro sarebbe un'implementazione concreta della logica di accesso ai dati di Entity Framework.
2) Il modello di repository è ancora valido quando non si utilizza un ORM e si utilizza ADO.net per l'accesso ai dati e il popolamento dei dati degli oggetti da soli?
Penso che spetti a te decidere quale modello è valido o meno. Ho usato un modello di repository nel livello di presentazione. Una cosa da tenere a mente è che alla gente piace gettare le responsabilità nei repository. Prima che tu lo sappia, la tua classe di repository ballerà, canterà e farà ogni sorta di cose. Vuoi evitare questo.
Ho visto una classe di repository che è iniziata con responsabilità GetAll, GetById, Update ed Delete, il che va bene. Quando il progetto fu completato, quella stessa classe aveva dozzine di metodi (responsabilità) che non avrebbero mai dovuto essere lì. Ad esempio GetByForename, GetBySurname, UpdateWithExclusions e tutti i tipi di cose folli.
Qui entrano in gioco query e comandi.
3) Se si utilizza un ORM ma non il modello di repository, dove vengono mantenute le query di uso comune. Sarebbe saggio rappresentare ogni query come una classe e avere una sorta di factory di query per creare istanze?
Penso che sia una buona idea usare query e comandi invece di repository. Faccio quanto segue:
Definire l'interfaccia per una query. Questo ti aiuterà a testare l'unità. Per esempiopublic interface IGetProductsByCategoryQuery { ... }
Definire un'implementazione concreta per una query. Sarai in grado di iniettarli attraverso il framework IoC di tua scelta. Per esempiopublic class GetProductsByCategoryQuery : IGetProductsByCategoryQuery
Ora invece di inquinare il repository con dozzine di responsabilità, raggruppo semplicemente le mie query in spazi dei nomi. Ad esempio, un'interfaccia per la query sopra può risiedere in: Company.SolutionName.Products.Queries
e l'implementazione può risiedere inCompany.SolutionName.Products.Queries.Implementation
Quando si tratta di aggiornare o rimuovere i dati, utilizzo il modello di comando allo stesso modo.
Alcuni potrebbero non essere d'accordo e dire che prima che il progetto sia completo avrai decine di classi e spazi dei nomi. Sì lo farai. Nella mia mente è una buona cosa come puoi navigare attraverso la soluzione in IDE di tua scelta e vedere immediatamente quale tipo di responsabilità ha un determinato componente. Se invece hai deciso di utilizzare un modello di repository, dovrai guardare all'interno di ogni classe di repository cercando di capire le sue responsabilità.