Shakir Kasmani
Shakir Kasmani

Reputation: 79

How to add Dependency Injection in Flutter with Provider

void main() => runApp(MultiProvider(providers: [
      ChangeNotifierProvider(
        create: (BuildContext context) => QuoteViewModel(),
      ),
      ChangeNotifierProvider(
        create: (BuildContext context) => AuthorViewModel(),
      ),
    ], child: MyApp()));

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Poems',
      home: PoemsListPage(),
    );
  }
}

main.dart

class QuoteListPage extends StatefulWidget {
  @override
  _QuoteListPageState createState() => _QuoteListPageState();
}

class _QuoteListPageState extends State<QuoteListPage> {
  @override
  Widget build(BuildContext context) {
    final model = Provider.of<QuoteViewModel>(context);
    return Scaffold(
      appBar: AppBar(title: Text('Poems List')),
      body: _buildBody(model.getQuotes()),
    );
  }

  Widget _buildBody(List<Quote> quotes) => ListView(
        children: quotes
            .map((quote) => ListTile(
                  title: Text(quote.body),
                ))
            .toList(),
      );
}

quoteListPage.dart

class Quote {
  final String id;
  final String authorId;
  final String body;

  Quote(this.id, this.authorId, this.body);
}

class Author {
  final String id;
  final String name;

  Author(this.id, this.name);
}

models.dart

class Repository {
  final Api _api = Api();
  final Database _database = Api();

  List<Quote> getQuotes() => [];

  List<Author> getAuthors() => [];
}

repository.dart

class QuoteViewModel with ChangeNotifier {
  final Repository _repository = Repository();

  List<Quote> getQuotes() => _repository.getQuotes();
}

class AuthorViewModel with ChangeNotifier {
  final Repository _repository = Repository();

  List<Author> getAuthors() => _repository.getAuthors();
}

notifiers.dart

I had tried using ProxyProvider after reading an article on Medium but it ends with the error "This is likely a mistake, as provider will not automatically update dependents"

List<SingleChildWidget> globalProviders = [
  Provider.value(value: Api()),
  Provider.value(value: Database()),
  ProxyProvider2<Api, Database, Repository>(
    update: (_, api, database, __) => Repository(api, database),
  ),
  ProxyProvider<Repository, QuoteViewModel>(
    update: (_, repo, __) => QuoteViewModel(repo),
  ),
  ProxyProvider<Repository, AuthorViewModel>(
    update: (_, repo, __) => AuthorViewModel(repo),
  )
];

void main() => runApp(
      MultiProvider(
        providers: globalProviders,
        child: MyApp(),
      ),
    );

main.dart (updated)

class Repository {
  final Api _api;
  final Database _database;

  Repository({@required api, @required database})
      : _api = api,
        _database = database;

  List<Quote> getQuotes() => [];

  List<Author> getAuthors() => [];
}

repository.dart(Updated)

class QuoteViewModel with ChangeNotifier {
  final Repository _repository;

  QuoteViewModel({@required repository}) : _repository = repository;

  List<Quote> getQuotes() => _repository.getQuotes();
}

class AuthorViewModel with ChangeNotifier {
  final Repository _repository;

  AuthorViewModel({@required repository}) : _repository = repository;

  List<Author> getAuthors() => _repository.getAuthors();
}

notifiers.dart(Updated)

Upvotes: 5

Views: 8353

Answers (1)

Omatt
Omatt

Reputation: 10529

Flutter has a guide on using the provider package that could help you out. https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple It'll be helpful if you could be more specific with the issue that you're having with provider.

Upvotes: 1

Related Questions