title: Flutter dependency injection set-up problem with get_it
body: <p>I'm trying to learn how to setup the dependency injection in flutter projects and I faced with one problem:</p>
  <pre><code>I/flutter (14507): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
  I/flutter (14507): The following assertion was thrown building _InheritedProviderScope&lt;NumberTriviaBloc&gt;(value: null):
  I/flutter (14507): No type GetConcreteNumberTrivia is registered inside GetIt.
  I/flutter (14507):  Did you forget to pass an instance name?
  I/flutter (14507): (Did you accidentally do  GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;did you
  I/flutter (14507): forget to register it?)
  I/flutter (14507): 'package:get_it/get_it_impl.dart':
  I/flutter (14507): Failed assertion: line 251 pos 14: 'instanceFactory != null'
  I/flutter (14507): 
  I/flutter (14507): The relevant error-causing widget was:
  I/flutter (14507):   _InheritedProviderScope&lt;NumberTriviaBloc&gt;
  </code></pre>
  <p>The dependency initialization:</p>
  <pre><code>final sl = GetIt.instance;
  
  void init() {
    //! Features - Number Trivia
    //* Bloc
    sl.registerFactory&lt;NumberTriviaBloc&gt;(() =&gt; NumberTriviaBloc(concrete: sl(), inputConverter: sl(), random: sl()));
  
    //* Use cases
    sl.registerLazySingleton&lt;UseCase&lt;NumberTrivia, Params&gt;&gt;(() =&gt; GetConcreteNumberTrivia(sl()));
    sl.registerLazySingleton&lt;UseCase&lt;NumberTrivia, NoParams&gt;&gt;(() =&gt; GetRandomNumberTrivia(sl()));
  
    //* Repository
    sl.registerLazySingleton&lt;NumberTriviaRepository&gt;(() =&gt; NumberTriviaRepositoryImplementation(
        localDataSource: sl(), networkInfo: sl(), remoteDataSource: sl()));
  
    //* Data sources
    sl.registerLazySingleton&lt;NumberTriviaRemoteDataSource&gt;(
        () =&gt; NumberTriviaRemoteDataSourceImpl(client: sl()));
  
    sl.registerLazySingleton&lt;NumberTriviaLocalDataSource&gt;(
        () =&gt; NumberTriviaLocalDataSourceImpl(sharedPreferences: sl()));
  
    //! Core
    sl.registerLazySingleton&lt;InputConverter&gt;(() =&gt; InputConverter());
    sl.registerLazySingleton&lt;NetworkInfo&gt;(() =&gt; NetworkInfoImpl(sl()));
  
    //! External
    sl.registerLazySingletonAsync&lt;SharedPreferences&gt;(() =&gt; SharedPreferences.getInstance());
    sl.registerLazySingleton&lt;http.Client&gt;(() =&gt; http.Client());
    sl.registerLazySingleton&lt;DataConnectionChecker&gt;(() =&gt; DataConnectionChecker());
  }
  </code></pre>
  <p>I can't understand what the problem, here is the code for other stuff initialization:</p>
  <pre><code>class NumberTriviaBloc extends Bloc&lt;NumberTriviaEvent, NumberTriviaState&gt; {
    final GetConcreteNumberTrivia getConcreteNumberTrivia;
    final GetRandomNumberTrivia getRandomNumberTrivia;
    final InputConverter inputConverter;
  
    NumberTriviaBloc(
        {@required GetConcreteNumberTrivia concrete,
        @required GetRandomNumberTrivia random,
        @required this.inputConverter})
        : assert(concrete != null),
          assert(random != null),
          assert(inputConverter != null),
          getConcreteNumberTrivia = concrete,
          getRandomNumberTrivia = random;
    ...
  }
  
  class GetConcreteNumberTrivia implements UseCase&lt;NumberTrivia, Params&gt;{
    final NumberTriviaRepository repository;
  
    GetConcreteNumberTrivia(this.repository);
  
    @override
    Future&lt;Either&lt;Failure, NumberTrivia&gt;&gt; call(Params params) async {
      return await repository.getConcreteNumberTrivia(params.number);
    }
  }
  
  class GetRandomNumberTrivia implements UseCase&lt;NumberTrivia, NoParams&gt; {
    final NumberTriviaRepository repository;
  
    GetRandomNumberTrivia(this.repository);
  
    @override
    Future&lt;Either&lt;Failure, NumberTrivia&gt;&gt; call(NoParams params) async {
      return await repository.getRandomNumberTrivia();
    }
  }
  
  class NumberTriviaRepositoryImplementation implements NumberTriviaRepository {
    final NumberTriviaRemoteDataSource remoteDataSource;
    final NumberTriviaLocalDataSource localDataSource;
    final NetworkInfo networkInfo;
  
    NumberTriviaRepositoryImplementation(
        {@required this.remoteDataSource,
        @required this.localDataSource,
        @required this.networkInfo});
    ...
  }
  
  class NumberTriviaRemoteDataSourceImpl implements NumberTriviaRemoteDataSource {
    final http.Client client;
  
    NumberTriviaRemoteDataSourceImpl({@required this.client});
    ...
  }
  
  class NumberTriviaLocalDataSourceImpl implements NumberTriviaLocalDataSource {
    final SharedPreferences sharedPreferences;
  
    NumberTriviaLocalDataSourceImpl({@required this.sharedPreferences});
    ...
  }
  
  class InputConverter {}
  
  class NetworkInfoImpl extends NetworkInfo {
    final DataConnectionChecker connectionChecker;
  
    NetworkInfoImpl(this.connectionChecker);
    ...
  }
  </code></pre>
  <p>The Widgets is:</p>
  <pre><code>void main() {
    di.init();
    runApp(MyApp());
  }
  
  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primaryColor: Colors.green.shade800,
          accentColor: Colors.green.shade600,
        ),
        home: NumberTriviaPage(),
      );
    }
  }
  
  class NumberTriviaPage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Number Trivia'),
        ),
        body: SingleChildScrollView(child: buildBody(context)),
      );
    }
  
    BlocProvider&lt;NumberTriviaBloc&gt; buildBody(BuildContext context) {
      return BlocProvider&lt;NumberTriviaBloc&gt;(
        create: (_) =&gt; sl&lt;NumberTriviaBloc&gt;(),
        child: Center(
          child: Padding(
            padding: const EdgeInsets.all(10),
            child: Column(
              children: &lt;Widget&gt;[
                SizedBox(
                  height: 10,
                ),
                BlocBuilder&lt;NumberTriviaBloc, NumberTriviaState&gt;(
                  // ignore: missing_return
                  builder: (context, state) {
                    if (state is Empty) {
                      return MessageDisplay(
                        message: 'Start searching',
                      );
                    } else if (state is Loading) {
                      return LoadingWidget();
                    } else if (state is Loaded) {
                      return TriviaDisplay(
                        numberTrivia: state.trivia,
                      );
                    } else if (state is Error) {
                      return MessageDisplay(
                        message: state.message,
                      );
                    }
                  },
                ),
                SizedBox(
                  height: 20,
                ),
                TriviaControl()
              ],
            ),
          ),
        ),
      );
    }
  }
  </code></pre>
  <p>I can't figure out why that not working for me.
  I following the tutorial on youtube, and also checked code from this tutorial on github repository, but that won't help me.
  So can you explain to me what's going on?</p>
  <p>I got a new error with help of tnc1997 answer:</p>
  <pre><code>lib/injection_container.dart:27:91: Error: The argument type 'NumberTriviaRepository/*1*/' can't be assigned to the parameter type 'NumberTriviaRepository/*2*/'.
   - 'NumberTriviaRepository/*1*/' is from 'package:clean_architecture/features/number_trivia/domain/repositories/number_trivia_repository.dart' ('lib/features/number_trivia/domain/repositories/number_trivia_repository.dart').
   - 'NumberTriviaRepository/*2*/' is from 'lib/features/number_trivia/domain/repositories/number_trivia_repository.dart'.
    sl.registerLazySingleton&lt;UseCase&lt;NumberTrivia, NoParams&gt;&gt;(() =&gt; GetRandomNumberTrivia(sl&lt;NumberTriviaRepository&gt;()));
  </code></pre>
  <p>This is the same file, and one line below uses similar contract</p>
  <pre><code>//* Use cases
    sl.registerLazySingleton&lt;UseCase&lt;NumberTrivia, Params&gt;&gt;(() =&gt; GetConcreteNumberTrivia(sl&lt;NumberTriviaRepository&gt;()));
    sl.registerLazySingleton&lt;UseCase&lt;NumberTrivia, NoParams&gt;&gt;(() =&gt; GetRandomNumberTrivia(sl&lt;NumberTriviaRepository&gt;()));
  
    //* Repository
    sl.registerLazySingleton&lt;NumberTriviaRepository&gt;(() =&gt; NumberTriviaRepositoryImplementation(
        localDataSource: sl&lt;NumberTriviaLocalDataSource&gt;(), networkInfo: sl&lt;NetworkInfo&gt;(), remoteDataSource: sl&lt;NumberTriviaRemoteDataSource&gt;()));
  </code></pre>
  <p>And now I'm a lot more confused then before</p>