Standardowy, nowo utworzony projekt ASP.NET MVC zawiera bezpośrednie odwołania do bazy danych w warstwie kontrolerów. Dziś nieco zmienimy to podejście, dokładając po środku warstwę abstrakcji - repozytorium generyczne.

Wielu uważa, że tworzenie repozytorium współpracującego z Entity Framework jest niepotrzebne, gdyż operując na standardowym obiekcie DbContext można osiągnąć ten sam, zamierzony efekt. Owszem, można. Ja jednak implementuję je ze względu na to, że dodatkowa warstwa umożliwia lepszą organizację projektu, ułatwia testowanie i redukuje ilość zduplikowanego kodu.

Zanim skupimy się na samym repozytorium, utwórzmy interfejs, po którym będą dzieczyć wszystkie modele w aplikacji. Po co? Po to, by wyposażyć je w takie właściwości jak np. flaga IsDeleted. Dobrą praktyką jest nie usuwanie z bazy danych wpisów, które usuwamy z poziomu interfejsu. Taki dodatkowy poziom “zabezpieczenia” danych przed utratą na pewno nie zaszkodzi. Często dodaje się również właściwości dotyczące modyfikacji wpisów, oczywiście wedle uznania

 

public interface IModel
{
    int Id { get; set; }

    bool? IsDeleted { get; set; }

    DateTime? DeletedDate { get; set; }
}

 

Interfejs naszego repozytorium prezentuje się następująco:

 

public interface IRepository
{
    T Find<T>(int id, params Expression<Func<T, object>>[] includeItems) where T : class, IModel;

    T Find<T>(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeItems) where T : class, IModel;

    IQueryable<T> All<T>(Expression<Func<T, bool>> predicate = null) where T : class, IModel;

    void Add<T>(T model) where T : class, IModel;

    void Update<T>(T model) where T : class, IModel;

    void Delete<T>(int id) where T : class, IModel;

    void Save();
}

 

Wyodrębniłem sześć metod, w przypadku mało skomplikowanej aplikacji powinny w zupełności wystarczyć. Mamy pobieranie wpisu po ID, pobieranie wpisu po zadanym predykacie, pobieranie wielu wpisów, dodawanie, edycję i usuwanie - można by rzec, CRUD z bajerami. Dodatkowo, wywoływany po każdej z operacji zapis do bazy danych w osobnej metodzie. W kolejnej części omówimy implementację naszego repozytorium, już za kilka dni. Ja również nie mogę się doczekać :)