ASP.NET Core ułatwia w znaczący sposób IoC. Przede wszystkim wbudowano w framework dosyć prostą implementację IoC. Oznacza to, że w wielu przypadkach nie trzeba już instalować zewnętrznych framework’ow takich jak AutoFac. W pliku Startup znajdziemy metodę ConfigureServices:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddApplicationInsightsTelemetry(Configuration); services.AddMvc(); }
Jeśli chcemy zarejestrować instancję jako singleton wtedy wystarczy:
services.AddSingleton<ITest, ConcreteTest>();
Nic więcej nie trzeba konfigurować. Instancja automatycznie zostanie wstrzyknięta do kontrolerów jak i widoków. Sprawa w przypadku kontrolerów wygląda prosto i wystarczy po prostu stworzyć konstruktor:
public HomeController(ITest test) { _test = test; }
W przypadku widoków, również możemy korzystać z wstrzykniętych instancji:
@using Microsoft.Extensions.Configuration @inject ITest test @{ ViewData["Title"] = "About"; } <h2>@ViewData["Title"].</h2> <h3>@ViewData["Message"]</h3> @test.GetText()
AddSingleton tworzy oczywiście pojedynczą instancję. Istnieje również metoda AddTriansient:
services.AddTransient<ITest, ConcreteTest>();
Tworzy ona nową instancję za każdym razem, gdy dochodzi do wstrzyknięcia.
Inny sposób to AddScoped:
services.AddScoped<ITest, ConcreteTest>();
AddScoped będzie współdzielić instancję w ramach tego samego zapytania. Przydatne, kiedy mamy wiele klas do których wstrzykujemy ten sam typ. W wielu przypadkach nie ma potrzeby tworzenia osobnych instancji.
W ramach ciekawostek warto poczytać o przyszłości wbudowanego DI w tym wątku na GitHubie:
https://github.com/aspnet/DependencyInjection/pull/416
i przeniesionej dyskusji tutaj:
https://github.com/aspnet/DependencyInjection/issues/433
Generalnie twórcy innych kontenerów DI mieli sporo zastrzeżeń co do zachowania i interfejsu jakim się charakteryzuje wbudowany kontener. Przede wszystkim taki -> http://blog.ploeh.dk/2014/05/19/conforming-container/
Bardzo ciekawa i pouczająca lektura 🙂
Cześć, fajnie że to opisałeś, ale nadal nie rozumiem, po co się deklaruje, że gdy taki interfejs, to będzie taka klasa. Po co ten interfejs ? Nie można zamiast pisać:
———————————————–
public HomeController(ITest test)
{
_test = test;
}
————————————————
to pisać:
public HomeController()
{
_test = new Test();
}
———————————————–
Nie kumam w ogóle tej idei, dla mnie jest zbędna.