Korzystanie z repozytorium w ASP.NET CORE 1.0

W poprzednim wpisie stworzyłem repozytorium aplikacji WPM. Teraz przyszła kolej na wykorzystanie tego repozytorium w praktyce.
Wydawało by się że najprostszym sposobem na korzystanie z repozytorium jest tworzenie nowej instancji wszędzie tam, gdzie jest to potrzebne:

public void JakasMetoda()
{
   IWPMRepository repository = new MsSqlContext();
   var creds = repository.GetAll<WPMCredential>();
}

Problem się zacznie gdy będziemy chcieli zmienić źródło danych (zmienimy typ bazy, albo będziemy chcieli skorzystać z innego ORM-a). W małych projektach możemy przelecieć po tych paru plikach z kodem i ręcznie pozamieniać klasy, lecz o wiele łatwiej i przyjemniej przewidzieć taką sytuację wcześniej i tak skonstruować program, aby nie trzeba było zmieniać za dużo w kodzie. Takim ułatwieniem są kontenery DI (czy IoC). Na temat DI (Dependency Injection – wstrzykiwanie zależności) jest napisane dużo w internecie, więc nie będę poruszał tego tematu. W wielkim skrócie działa to tak że mówimy do kontenera „daj mi obiekt który implementuje interfejs IRepository„, a kontener zwraca klasę MsSqlContext (lub inną, w zależności od konfiguracji).

public void JakasMetoda()
{
   IWPMRepository repository = kontenerDI.DajMi(IWPMRepository);
   var creds = repository.GetAll<WPMCredential>();
}

ServiceCollection

W ASP.NET Core 1.0 kontener DI mamy „z pudełka”: ServiceCollection. Jego użycie jest bardzo proste: w klasie Startup, w metodzie ConfigureServices dodajemy:

services.AddScoped<IWPMRepository, MsSqlContext>();

Czyli kontener na żądanie klasy implementującej interfejs IWPMRepository zwróci klasę MsSqlContext.
Dodatkowo, aby zagrało nam wszystko do końca, w tym samym miejscu dodajemy:

services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<MsSqlContext>();

Po zmianach metoda wygląda w całości tak:

        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);
            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<MsSqlContext>();
            services.AddScoped<IWPMRepository, MsSqlContext>();
            services.AddMvc();
        }

Kontrolery

Teraz musimy jakoś wykorzystać skonfigurowany powyżej kontener w kontrolerach. Aby to uczynić, dodajemy konstruktor do kontrolera z odpowiednim parametrem. Cały kontroler po zmianach wygląda tak:

    public class CredentialController : Controller
    {
        private IWPMRepository _repository;
        public CredentialController(IWPMRepository repository)
        {
            _repository = repository;
        }
        public IActionResult Index()
        {
            var cred = _repository.GetAll<WPMCredential>(r => true).ToList();
            return View(cred);
        }
    }

Parametrem konstruktora (@4) jest klasa która implementuje IWPMRepository. Jak widać kontroler nie wie że korzysta z repozytorium MsSqlContext, …i mu ta wiedza nie jest do niczego potrzebna. W tym przypadku kontroler wykorzystuje tylko metodę GetAll()(@10), która jest zdefiniowana w interfejsie IWPMRepository.
Co trzeba zrobić po stronie ASP aby zmienić bazę? Zmienić tylko wpisy w klasie Startup, a cała reszta powinna działać bez problemu.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *