Flutter BLoC and get_it is a great solution for dependency injection. Make sure you go ahead and install get_it. Once you do it you may create an instance out of it.
See how we get the instance to GetIt and save in a variable called sl
. This instance sl does all the magic. It get the instance of GetIt and call other helper functions. Then we need to register our dependency.
There are three ways to register dependency with GetIt.
registerFactory()
In general the next thing we do is to call sl.registerFactory()
method. Inside the method, we have to pass the object that should be registered as dependency.
Let's understand how the basic dependency injection works with GetIt. To inject dependency you need to use one of the above function and mention a class name that needs to injected.
The simplest way doing it is passing your dependency inside an anonymous function. Let's take a look at the example below
Here you see that inside registerFactory we return AuthBloc and AuthBloc is a Bloc class for handing events and emitting new states.
AuthBloc depends on a few other classes like SignIn, SignUp, ForgotPassword and Updateuser class. Each of these classes instances are assigned by calling sl().
sl() would automatically find those instances and assign to AuthBloc.
Now, there's a great benefit of using registerFactory, it always permits us to get a new instance of class. AuthBloc is class that should be always new, should always return a new instance when user request one specially during login and logout.
AuthBloc may also involve other features like reset password and forget password. Thats why AuthBloc has to wrap inside registerFactory().
If you want long living singleton instance of your class, then wrap your class using registerSingleton() or registerLazySingleton().
In general you just want to use registerFactory() and registerLazySingleton().
registerLazySingleton()
Most of your class instances should be created inside registerLazySingleton(). These are pure dart classes in general. They should not be abstract classes either. Pure concrete classes with dependencies if needed.
All these classes are the usecases of clean architecture of BLoC, GetX or Riverpod
All the above classes are concrete dart classes and they may extend other abstract classes. Like here let's take a look at
Here you see GetCategories is a class which extends another class. That class is an abstract class. So inside registerLazySingleton() we must put a class that can create object or a derived class.
But we may inject a derived class from an interface. In the earlier picture, we see that there's a repo which is ProductRepo. This class ProductRepo is an abstract class and implemented by ProductRepoImpl. So ProductRepo is an interface now and ProductRepoImpl is the implementation of it.
Inject with Cubit
You may have a Cubit and it depends on a lot of dependencies. How do we load the dependencies? It's easy. We can do it by using registerFactory()
This is our CartAdapter and it extends Cubit with a state class. And we do see that it depends on lot of other classes. These classes are usually usecase class(I am talking in terms of clean architecture)
GetIt can find the related dependencies of the usecases and load them and inject in the Cubit.
Update screen
Here we will see how to update different part of the screen with the help GetIt. Now, this problem is not partycularly related to GetIt. But using GetIt, we can further optimize how we use BLoC.
So in this case GetIt comes as a BLoC rescuewer.
Of course you have to locate the bloc using sl() which is an instance of GetIt.