Co chcę osiągnąć?
Zarejestrować we wbudowanym kontenerze ASP.NET Core factory do tworzenia obiektów IPersonProvider.
Jak próbuję to zrobić?
Rejestruję IPersonProvider w kontenerze oraz fabrykę Func<IPersonProvider> (jak poniżej)
Rejestracja:
services.AddScoped<IPersonProvider, PersonProvider>();
services.AddSingleton<Func<IPersonProvider>>(sp => () => sp.GetService<IPersonProvider>());
Wywołanie:
public class HomeController : Controller
{
private readonly Func<IPersonProvider> _factory;
public HomeController(Func<IPersonProvider> factory)
{
_factory = factory;
}
[Route("/")]
public string Calculate()
{
var personProvider = _factory();
//.
//.
//.
return "test";
}
}
Jaki problem?
Ustawienie life cycli. Wydaje mi się, że sama factory powinna być Singleton (współdzielona przez aplikację), gdyż jest jedynie odpowiedzialna za utworzenie obiektu IPersonProvider, gdy jest potrzebny. IPersonProvider z kolei nie nadaje się na Singleton, ale jak najbardziej może być współdzielona per web request (Scoped). Problem, że w przypadku rejestracji Singleton-Scoped dostaję błąd:
InvalidOperationException: Cannot resolve scoped service 'DependencyApp.Provider.IPersonProvider' from root provider.
O dziwo, gdy zmienię lifecycle dla IPersonProvider z AddScoped na AddTransient to działa. Aczkolwiek dużo bardziej preferowałbym Scoped, gdyż utworzenie IPersonProvider jest dość kosztowne, a jak najbardziej może być współdzielone per request.
Dziękuję z góry za jakieś sugestie dlaczego tak to działa.