Scoped w Singletonie

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

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?

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.

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.
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ę.

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

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ść?

1 użytkowników online, w tym zalogowanych: 0, gości: 1