Dziwne bo przerabiałem jedną z literatur jaką jest Pro ASP.NET MVC 4 i w niej korzystali właśnie tak z repozytoriów.
Nie jest to dziwne. Większość ludzi nie rozumie ani wzorca repozytorium (uznając go za warstwę dostępu do bazy danych) ani MVC (myśląc, że Model = baza danych, a Kontroler odpowiada za wszystko: logikę prezentacji, aplikacji i biznes, a w ogóle to MVC oznacza aplikację trójwarstwową).
Co nie zmienia faktu, że jest to dobra książka, jeśli chcemy się nauczyć technologii ASP.NET MVC, ale nie projektowania sensownych aplikacji.
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
źródło: http://martinfowler.com/eaaCatalog/repository.html
A tutaj dobre wyjaśnienie: http://www.sapiensworks.com/blog/post/2012/02/22/The-Repository-Pattern-Explained.aspx
i dobry zestaw rad: http://www.sapiensworks.com/blog/post/2013/10/07/Tips-And-Tricks-For-The-Repository-Pattern.aspx
In the MVC paradigm the user input, the modeling of the external world, and the visual feedback to the user are explicitly separated and handled by three types of object, each specialized for its task. The view manages the graphical and/or textual output to the portion of the bitmapped display that is allocated to its application. The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate. Finally, the model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).
źródło: http://st-www.cs.illinois.edu/users/smarch/st-docs/mvc.html
Trochę więcej na ten temat: http://www.martinfowler.com/eaaDev/uiArchs.html
I jeszcze więcej: http://lostechies.com/derekgreer/2007/08/25/interactive-application-architecture/
W takim razie jak poprawnie używać repozytoriów nie łamiąc MVC ?
Kontrolery powinny być jak najprostsze, powinny jedynie obsługiwać żądania użytkownika, wywoływać operacje na Modelu i przekierowywać do odpowiednich Widoków.
Ja robię tak, że z kontrolera wołam metodę application service czyli klasy, która stanowi zbiór procesów biznesowych aplikacji. Dane od tego serwisu do Kontrolera i z powrotem przekazuję za pomocą ViewModeli. Application service może być dowolnie skomplikowana, w prostym przypadku sama przeprowadzi operacje bezpośrednio na encjach i kontekście EF (albo lepiej ISession z NHibernate), a jeśli logika aplikacji jest bardzo skomplikowana, to nic nie szkodzi, żeby application service ukrywał przed kontrolerami model zbudowany zgodnie z DDD... Możliwości są nieograniczone, należy je tylko dopasować do złożoności naszych problemów.
Jeśli aplikacja ma mieć miliard użytkowników, to application service łatwo przerobić na web service, i postawić na oddzielnym serwerze. Przy moim podejściu niemalże gratis mamy warstwy fizyczne, gdy tylko będą potrzebne.
No i najważniejsze - dzięki temu oddzielona jest aplikacja (czyli oprogramowane procesy biznesowe) od swoich klientów. Bo aplikacja webowa napisana w ASP.NET MVC to jeden z możliwych klientów aplikacji. Mogą też być inne. A najważniejszym klientem, który powinien powstać jeszcze przed napisaniem kodu aplikacji, są testy jednostkowe.
A wady? Trzeba to napisać... a dużo łatwiej wstawić generyczne repozytorium w kontrolery i tworzyć spaghetti. No, ale to dobre spaghetti, w końcu mamy modne MVC i powszechnie uznawane za profesjonalizm repozytoria, więc jesteśmy modni, profesjonalni i wielowarstwowi... zupełnie jak Shrek.