In Flutter, I feel a bit lost with how I create my params for classes, and knowing what is the best way to create those params. Usually, the params are just classes to inject into another class, to perform tasks. It doesn't really seem to matter how those params are created functionality-wise, since the code works with all manner of creation methods. I see online people talking about service locators, singletons, dependency injection. Riverpod states on the website "Providers are a complete replacement for patterns like Singletons, Service Locators, Dependency Injection or InheritedWidgets." So I guess I don't need a service locator, since I use Riverpod. However I can't find anything online on how I can inject a service with Riverpod providers. I can see you can read a provider with no context with ProviderContainer().read but is this for use as service injection? Is this a singleton so pretty much a service locator? In the Riverpod example, it states that you don't need ProviderContainer().read for Flutter, which kind of sounds like it isn't a replacement for anything like a service locator then:
// Where the state of our providers will be stored.
// Avoid making this a global variable, for testability purposes.
// If you are using Flutter, you do not need this.
final container = ProviderContainer();
Here is a code example, a field in a class which is a ViewModel which takes some use cases as params. Use cases here are domain layer actions classes which call repositories to do external stuff like API requests or local storage manipulations.
final CreateUserViewModel createUserViewModel =
CreateUserViewModel(SavePasswordLocallyUseCase(), CreateUserUseCase());
...
So I just literally created them in-line like SavePasswordLocallyUseCase(), in order to inject them. This is defnitely the easiest approach, with the least code. I guess it might be less efficient since it is creating a new one every time, though i don't see that usually making a visible difference. Will these params that are created in this manner be cleaned up by the garbage collector? What is the repercussion of doing this?
If I had to inject a type AuthenticationService, should I be using a service locator or creating them inline like AuthenticationService(), or using Riverpod's ProviderContainer.read()?