Chcę zaimplementować wstrzykiwanie zależności (DI) w programie ASP.NET Core. Po dodaniu tego kodu do ConfigureServices
metody działają obie metody.
Jaka jest różnica między metodami services.AddTransient
i service.AddScoped
w programie ASP.NET Core?
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddScoped<IEmailSender, AuthMessageSender>();
}
c#
asp.net-core
.net-core
Elvin Mammadov
źródło
źródło
Odpowiedzi:
TL; DR
Aby uzyskać dodatkowe wyjaśnienia, ten przykład z dokumentacji ASP.NET pokazuje różnicę:
Aby wykazać różnicę między tymi opcjami życiowych i rejestracyjnych, rozważmy prosty interfejs, który stanowi jeden lub więcej zadań jako operacja z unikalnym identyfikatorem,
OperationId
. W zależności od tego, w jaki sposób skonfigurujemy czas życia tej usługi, kontener zapewni klasę żądającą takie same lub różne wystąpienia usługi. Aby wyjaśnić, który okres istnienia jest wymagany, utworzymy jeden typ dla okresu istnienia:Implementujemy te interfejsy za pomocą jednej klasy,
Operation
która akceptuje identyfikator GUID w swoim konstruktorze lub używa nowego identyfikatora GUID, jeśli nie został podany:Następnie za
ConfigureServices
każdy typ jest dodawany do kontenera zgodnie z jego nazwanym czasem życia:Pamiętaj, że
IOperationSingletonInstance
usługa korzysta z określonej instancji o znanym identyfikatorzeGuid.Empty
, więc będzie jasne, kiedy ten typ jest używany. Zarejestrowaliśmy również opcjęOperationService
zależną od każdego z pozostałychOperation
typów, dzięki czemu w żądaniu będzie jasne, czy ta usługa otrzymuje tę samą instancję, co kontroler, czy nową, dla każdego typu operacji. Wszystko, co robi ta usługa, ujawnia swoje zależności jako właściwości, dzięki czemu można je wyświetlać w widoku.Aby zademonstrować czasy życia obiektu w ramach oddzielnych indywidualnych żądań do aplikacji i pomiędzy nimi, próbka zawiera
OperationsController
żądanie, które żąda każdego rodzaju,IOperation
jak równieżOperationService
. NastępnieIndex
akcja wyświetla wszystkie wartości kontrolera i usługiOperationId
.Teraz wysyłane są dwa osobne żądania do tej akcji kontrolera:
Obserwuj, które
OperationId
wartości różnią się w obrębie żądania i między żądaniami.Obiekty przejściowe są zawsze różne; nowa instancja jest dostarczana do każdego kontrolera i każdej usługi.
Obiekty o zasięgu są takie same w żądaniu, ale różne dla różnych żądań
Obiekty Singleton są takie same dla każdego obiektu i każdego żądania (niezależnie od tego, czy instancja jest dostarczona
ConfigureServices
)źródło
W wstrzykiwaniu zależności platformy .NET istnieją trzy główne okresy istnienia:
Singleton, który tworzy pojedyncze wystąpienie w całej aplikacji. Tworzy instancję po raz pierwszy i ponownie wykorzystuje ten sam obiekt we wszystkich wywołaniach.
Dożywotnie usługi o określonym zakresie są tworzone raz na żądanie w ramach zakresu. Jest to ekwiwalent singletonu w obecnym zakresie. Na przykład w MVC tworzy jedno wystąpienie dla każdego żądania HTTP, ale używa tego samego wystąpienia w innych wywołaniach w ramach tego samego żądania internetowego.
Przejściowe dożywotnie usługi są tworzone za każdym razem, gdy są wymagane. Ten okres użytkowania działa najlepiej w przypadku lekkich, bezpaństwowych usług.
Tutaj możesz znaleźć i przykłady, aby zobaczyć różnicę:
Wstrzykiwanie zależności ASP.NET 5 MVC6 w 6 krokach (link do archiwum internetowego z powodu martwego łącza)
Twój gotowy do wstrzykiwania zależności ASP.NET: ASP.NET 5
A to jest link do oficjalnej dokumentacji:
Wstrzykiwanie zależności w programie ASP.NET Core
źródło
Transient, scoped i singleton definiują proces tworzenia obiektów w ASP DINET MVC core DI, gdy trzeba wstrzyknąć wiele obiektów tego samego typu. Jeśli dopiero zaczynasz przygodę z iniekcją zależności, możesz zobaczyć wideo DI IoC .
Możesz zobaczyć poniższy kod kontrolera, w którym zażądałem dwóch wystąpień „IDal” w konstruktorze. Transient, Scoped i Singleton określają, czy to samo wystąpienie zostanie wstrzyknięte w „_dal” i „_dal1”, czy w inne.
Przejściowy: W stanach przejściowych nowe instancje obiektów zostaną wstrzyknięte w jednym żądaniu i odpowiedzi. Poniżej znajduje się migawka, na której wyświetlałem wartości GUID.
Zakres: W zakresie zakres tego samego wystąpienia obiektu zostanie wstrzyknięty w jednym żądaniu i odpowiedzi.
Singleton: W singletonie ten sam obiekt zostanie wstrzyknięty we wszystkie żądania i odpowiedzi. W takim przypadku zostanie utworzona jedna globalna instancja obiektu.
Poniżej znajduje się prosty schemat, który wyjaśnia powyższy fundament wizualnie.
Powyższe zdjęcie zostało narysowane przez zespół SBSS, kiedy brałem udział w szkoleniu ASP.NET MVC w Bombaju . Ogromne podziękowania należą się zespołowi SBSS za stworzenie powyższego obrazu.
źródło
new TService
. Scoped zbuforuje pierwszą inicjalizację tego „zakresu” (w większości przypadków żądanie HTTP). Singleton będzie buforował tylko jedno wystąpienie w całym okresie istnienia aplikacji, to proste. Powyższe diagramy są bardzo skomplikowane.Normalnie żądanie kodu powinno być wykonane za pomocą parametru konstruktora, jak w
Chciałem wskazać w odpowiedzi @ akazemis, że „usługi” w kontekście DI nie oznaczają usług RESTful; usługi są implementacjami zależności zapewniających funkcjonalność.
źródło
AddSingleton ()
AddSingleton () tworzy pojedyncze wystąpienie usługi, gdy jest najpierw żądane, i ponownie wykorzystuje to samo wystąpienie we wszystkich miejscach, w których ta usługa jest potrzebna.
AddScoped ()
W usłudze o zasięgu z każdym żądaniem HTTP otrzymujemy nową instancję. Jednak w ramach tego samego żądania HTTP, jeśli usługa jest wymagana w wielu miejscach, np. W widoku i kontrolerze, to ta sama instancja jest zapewniona dla całego zakresu tego żądania HTTP. Ale każde nowe żądanie HTTP otrzyma nową instancję usługi.
AddTransient ()
W przypadku usługi przejściowej nowa instancja jest dostarczana za każdym razem, gdy żądana jest instancja usługi, niezależnie od tego, czy jest objęta zakresem tego samego żądania HTTP, czy też różnych żądań HTTP.
źródło
Po znalezieniu odpowiedzi na to pytanie znalazłem genialne wyjaśnienie z przykładem, którym chciałbym się z tobą podzielić.
Możesz obejrzeć film pokazujący różnice TUTAJ
W tym przykładzie mamy następujący kod:
HomeController
Utwórz widok
Startup.cs
Skopiuj i wklej ten kod i naciśnij przycisk Utwórz w widoku i przełączaj się między nimi
AddSingleton
,AddScoped
aAddTransient
za każdym razem otrzymasz inny wynik, który może pomóc w zrozumieniu tego wyjaśnienia:źródło
Którego użyć
Przemijający
Zakres
Singel
Używaj singletonów, gdy chcesz utrzymać stan aplikacji. Konfiguracja lub parametry aplikacji, usługa rejestrowania, buforowanie danych to tylko niektóre z przykładów użycia singletonów.
Wstrzykiwanie usługi o różnych cyklach życia do innej
źródło
Jak opisano tutaj (ten link jest bardzo przydatny) z przykładem,
źródło
Rejestracja usług
Program ASP.NET core udostępnia 3 następujące metody rejestrowania usług w kontenerze wstrzykiwania zależności. Stosowana przez nas metoda określa czas życia zarejestrowanej usługi.
AddSingleton () - Jak sama nazwa wskazuje, metoda AddSingleton () tworzy usługę Singleton. Usługa Singleton jest tworzona przy pierwszym żądaniu. Ta sama instancja jest następnie używana przez wszystkie kolejne żądania. Ogólnie rzecz biorąc, usługa Singleton jest tworzona tylko raz na aplikację i ta pojedyncza instancja jest używana przez cały czas życia aplikacji.
AddTransient () - Ta metoda tworzy usługę przejściową. Nowe wystąpienie usługi przejściowej jest tworzone za każdym razem, gdy jest ono wymagane.
AddScoped () - Ta metoda tworzy usługę o zasięgu. Nowa instancja usługi o zasięgu jest tworzona raz na żądanie w ramach zakresu. Na przykład w aplikacji internetowej tworzy 1 wystąpienie na każde żądanie HTTP, ale używa tego samego wystąpienia w innych wywołaniach w ramach tego samego żądania internetowego.
źródło