Scoped w Singletonie

Scoped w Singletonie
bakunet
  • Rejestracja:około 8 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:Polska
  • Postów:1608
0

Usiadłem do swojego projektu w którym API ma wykonywać cyklicznie jakąś pracę. W .Net 5-6 możemy zarejestrować serwisy które dziedziczą po BackgroundService lub IHostedService, oba funkcjonują jako singletony.

I wróciłem ponownie do problemu wstrzykiwania Scoped do Singletona. Od którejś wersji .Net rzuca to wyjątkiem.

Długi czas temu problem ten rozwiązałem za pomocą IServiceProvider.CreateScope().

Teraz chwilę pogooglałem i trafiem na podobny przykład: https://cezarywalenciuk.pl/blog/programing/backgroundservice-w-aspnet-core-i-cykl-zycia-scoped

Kopiuj
using (var scope = Services.CreateScope())
            {
                var scopedProcessingServices =
                    scope.ServiceProvider
                        .GetServices<IScopedProcessingService>();

                for (int i = 0; i < 10; i++)
                {
                    foreach (var scopedProcessingService in scopedProcessingServices)
                    {
                        await scopedProcessingService.DoWork(stoppingToken);
                    }
                    await Task.Delay(1000);
                }

            }
  1. Zastanawiam się czy jest elegantsze rozwiązanie tego problemu?

  2. Zastanawiam się też czy jeśli IScopedProcessingService jest wykorzystywane jedynie przez singletona, czy i w jakim wypadku jest sens rejestrować go jako Scoped?

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:6 dni
  • Lokalizacja:Wrocław
1
bakunet napisał(a):

I wróciłem ponownie do problemu wstrzykiwania Scoped do Singletona. Od którejś wersji .Net rzuca to wyjątkiem.

No i słusznie. Lepiej gdy biblioteka rzuci wyjątkiem, niż programista mięsem.

W czym problem, bo nie rozumiem? Jeśli coś wstrzykujesz do singletona, to staje się to efektywnie singletonem.

obscurity
  • Rejestracja:około 6 lat
  • Ostatnio:około 2 godziny
1
  1. Jakiego problemu?
  2. No jak masz serwis Scoped to znaczy że masz jakiś scope, jak chcesz utworzyć scope to używasz CreateScope.
    Jak nie masz tak naprawdę scope'a i używasz CreateScope tylko po to żeby nie rzucało wyjątkiem a tak naprawdę potrzebujesz singletona no to nie ma sensu.

"A car won't take your job, another horse driving a car will." - Horse influencer, 1910
bakunet
  • Rejestracja:około 8 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:Polska
  • Postów:1608
0
somekind napisał(a):

W czym problem, bo nie rozumiem? Jeśli coś wstrzykujesz do singletona, to staje się to efektywnie singletonem.

obscurity napisał(a):
  1. Jakiego problemu?

Cytat:

Warto także zaznaczyć, że wstrzykiwanie sobie "IServiceProvider" tworzy antywzorzec "ServiceLocator", ale w tym przypadku nie możemy tego uniknąć.

Ale po odpowiedziach wnioskuję że inaczej tego się zrobić nie da. Dziękuję.

obscurity
  • Rejestracja:około 6 lat
  • Ostatnio:około 2 godziny
0
bakunet napisał(a):

Cytat:

Warto także zaznaczyć, że wstrzykiwanie sobie "IServiceProvider" tworzy antywzorzec "ServiceLocator", ale w tym przypadku nie możemy tego uniknąć.

Ale po odpowiedziach wnioskuję że inaczej tego się zrobić nie da. Dziękuję.

Jeśli to cię martwi to IServiceProvider.CreateScope tak naprawdę wywołuje

Kopiuj
provider.GetRequiredService<IServiceScopeFactory>().CreateScope()

więc możesz wstrzykiwać zamiast tego IServiceScopeFactory jeśli poczujesz się lepiej. Samo wstrzyknięcie IServiceProvider nie tworzy żadnego antywzorca, są miejsca gdzie wstrzyknięcie go jest niezbędne, na przykład w fabryce która tworzy dynamicznie instancje przez ActivatorUtilities.CreateInstance() lub w widoku WPF kiedy musimy poprosić o ViewModel. Czy użycie ServiceProvidera w tym przypadku jest antywzorcem skoro tworzy zaledwie jedną, oczywistą zależność?


"A car won't take your job, another horse driving a car will." - Horse influencer, 1910

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.