Using a singleton for Bloc

4,378

The behavior stays the same. A singleton vs InheritedWidget doesn't change much

But it has a few architectural consequences, as you should use an InheritedWidget for BLoCs that aren't "instantiated only once throughout the app lifecycle."

Which means that:

  • you'll mix InheriedWidgets and Singletons in your app. Reducing consistency as you have two different way to create/use a BLoC
  • it becomes harder to adapt when the specs change. It is very possible that in the future, you may have to instantiate it more than once. That means you'd have to edit the whole application

On another note, singletons do not prevent some mistakes that InheritedWidgets do.

For example, it is impossible to have a circular dependency using InheritedWidgets, when it is definitely possible using singletons.


You're not winning much by using a Singleton vs InheritedWidget in term of code either.

There's a good chunk of libraries on Pub to make your job easier. Including provider:

runApp(
  Provider(
    value: MyBloc(),
    child: MyApp(),
  ),
);
Share:
4,378
Vamsi Krishna
Author by

Vamsi Krishna

Updated on December 10, 2022

Comments

  • Vamsi Krishna
    Vamsi Krishna over 1 year

    I know that some of my BLOCs will be instantiated only once throughout the app lifecycle. Is it bad practice or anti-pattern to create these BLOC classes as a singleton. Singleton can help in accessing the BLOC anywhere and also makes sure that the class is instantiated only once.

    I can also ensure to be safe when using one BLOC inside another BLOC and passing around the singleton as if it were "just another" implementation.

    What might be the effects of doing so?

    Edit

    I have two Blocs

    1. AuthenTicationBloc - this is a global bloc
    2. UserBloc - should exist only once (singleton)

    The AuthenTicationBloc has to use the UserBloc inside it. If I made UserBloc a singleton , it would make it easy to just use it as UserBloc().

    Othewise I had to create UserBloc as an instance variable in AuthenTicationBloc as follows:

    class AuthenTicationBloc {
      UserBloc _userBloc;
    
      AuthenTicationBloc({@required UserBloc userBloc}) : _userBloc = userBloc;
    
    
      myMethod(){
        //use the userBloc
        _userBloc.setDetails();
      }
    }
    
    
    runApp(
      UserBloc userBloc = UserBloc();
    
      Provider(
        value: AuthenTicationBloc(userBloc: userBloc),
        child: MyApp(),
      ),
    );
    

    If I had to use the UserBloc down the widgetchain somewhere else I had to make the UserBloc also be provided globally as follows right?

    UserBloc userBloc = UserBloc();
    
    MultiProvider(
      providers: [
        Provider<AuthenTicationBloc>(
          value: AuthenTicationBloc(userBloc:userBloc),
        ),
        Provider<UserBloc>(
          value: userBloc,
        ),
      ],
      child: MyApp(),
    );