Dependency Injection (DI) In Flutter :
- Supplies your objects with other objects that they depend on.
- Three forms of the accepted dependency injection in Flutter.
- InheritedWidgets
- get_it
- provider
For example :
classLoginService { Apiapi; }
LoginService depends on the Api object.The usual way to get to a dependency into a class is through the constructor.

Inherited Widget
- Inherited widget effectively allows you to provide access, through the BuildContext, to all it’s properties, to every widget in it’s subtree. It’s common in Flutter and is used for the Theme, MediaQueries and everything else the base app provides. This is how an empty InheritedWidget looks.
import'package:flutter/material.dart'; classInheritedInjectionextendsInheritedWidget{ final Widget child; InheritedInjection({Key key,this.child}):super(key: key, child: child); staticInheritedInjectionof(BuildContext context){ return(context.inheritFromWidgetOfExactType(InheritedInjection)asInheritedInjection); } @override bool updateShouldNotify(InheritedInjectionoldWidget){ returntrue; } }
Usage :
- The way inherited widgets are used is by wrapping the tree you want in the inherited widget. we want this widget to be supplied to our entire app so we’ll wrap the MaterialApp with the InheritedInjection widget.
classMyAppextendsStatelessWidget{ @override Widget build(BuildContext context){ returnInheritedInjection( child:MaterialApp( title:'Flutter Demo', theme:ThemeData( primarySwatch:Colors.blue, ), home:HomeView()), ); } }
- The way we access the inherited widget in our code is by using the .of call and passing the context. We can now update our HomeView and remove the AppInfo passed through the constructor as well as the class variable we kept. We can now make our HomeView look like this.
classHomeViewextendsStatelessWidget{ HomeView({Key key}):super(key: key); @override Widget build(BuildContext context){ varappInfo=InheritedInjection.of(context).appInfo; returnScaffold( body:Center( child:Text(appInfo.welcomeMessage), ), ); } }
- Now anywhere in the app where you want to use your AppInfo object all you’ll do is.
varappInfo = InheritedInjection.of(context).appInfo;
Pros
- This is how everything in Flutter is built.
- Forces one directional data flow.
Cons
- Boilerplate around instance tracking. Meaning when you want a new instance everytime you request the type you have to set that up. The same with if you want a singleton.
- Injecting into objects where the context is not available is almost impossible. You have to clutter up the InheritedWidget itself with all the setup and manually inject objects where the context is not available.
- Very verbose
Get_it
- No need to pass anything constructors just to access the data.
- Get it is what is known as a simple service locator. Traditionally you register your your types against an interface and provide the concrete implementation to it. This way you benefit from developing against an interface which also makes unit testing easier because you can provide test specific implementations.
pubspec
get_it
GetIt locator = GetIt.instance;
- If you really, REALLY need more than one GetIt instance please set allowMultipleInstancesto true to signal you know what you are doing.
GetIt locator = GetIt.asNewInstance();
GetIt.allowMultipleInstances=true;
- Factory: When you request an instance of the type from the service provider you’ll get a new instance every time.
- Singleton: Singletons can be registered in two ways. Provide an implementation upon registration or provide a lamda that will be invoked the first time your instance is requested (LazySingleton). The Locator keeps a single instance of your registered type and will always return you that instance.
Pros
- Can request type anywhere using the global locator
- Instance tracking is automatically taken care of by registering types as Factories or Singleton
- Can register types against interfaces and abstract your architecture from the
- implementation details
- Compact setup code with minimal boiler plate
Cons
- Disposing is not a top priority in the framework
- Loose coding guidelines that can lead to badly written software
- Global object usage which is the start of multi-directional data flow which is the opposite of what Flutter promotes
Provider
- It has specialised provider types like StreamProvider, ChangeNotifierProvider, ListenableProvider that can be used to architect your entire app.
pubspec
provider
- Similarly to the InheritedWidget, the Provider injected value is only available in it’s subtree. To get the value everywhere we will wrap our entire app in a provider.
classMyAppextendsStatelessWidget{ @override Widget build(BuildContext context){ returnProvider( builder:(context)=>AppInfo(), child:MaterialApp( title:'Flutter Demo', theme:ThemeData( primarySwatch:Colors.blue, ), home:Scaffold(), ), ); } }
- When you want to access the value from the provider all you have to do it.
@override Widget build(BuildContext context){ varappInfo=Provider.of<AppInfo>(context); returnScaffold( body:Center( child:Text(appInfo.welcomeMessage), ), ); }
Pros
- Great for StateManagement, my number one choice
- Forces one directional data flow
- The SpecialtyProviders removes loooots of boilerplate code
- Using the Consumers for your providers is neat and clean
- Supplies a way to dispose all provider objects
Cons
- Injecting into objects that doesn’t have a BuildContext requires lots of ProxyProvider stringing
home_view.dart
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'login_service.dart'; import 'locator.dart'; import 'user_service.dart'; class HomeView extends StatelessWidget { HomeView({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: MyList() ); } } class MyList extends StatelessWidget { const MyList({Key key}) : super(key: key); @override Widget build(BuildContext context) { return PostItem(); } } class PostItem extends StatelessWidget { const PostItem({Key key}) : super(key: key); @override Widget build(BuildContext context) { return PostMenu(); } } class PostMenu extends StatelessWidget { const PostMenu({Key key}) : super(key: key); @override Widget build(BuildContext context) { return PostAction(); } } class PostAction extends StatelessWidget { const PostAction({Key key}) : super(key: key); @override Widget build(BuildContext context) { return LikeButton(); } } class LikeButton extends StatelessWidget { const LikeButton({Key key}) : super(key: key); @override Widget build(BuildContext context) { // We have access to it anywhere in the app with this simple call var appInfo = Provider.of<LoginService>(context); var userService = locator<UserService>(); var appInfoService = locator<LoginService>(); return Container( child: Text(userService.userName + appInfoService.welcomeMessage), ); } }
login_service.dart
class LoginService { String get welcomeMessage => 'Hello from FilledStacks'; }
user_service.dart
class UserService { String userName = "filledstacks"; }
locator.dart
import 'package:get_it/get_it.dart'; import 'login_service.dart'; import 'home_view.dart'; import 'user_service.dart'; GetIt locator = GetIt.asNewInstance(); void setupLocator() { GetIt.allowMultipleInstances=true; locator.registerSingleton(UserService()); locator.registerFactory(() => LoginService()); }
pubspec.yaml
name: flutter_injection description: A new Flutter application. version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.2 get_it: provider: dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true
main.dart
import 'package:flutter_injection/home_view.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'login_service.dart'; import 'locator.dart'; void main() { setupLocator(); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Provider( builder: (context) => LoginService(), child: MaterialApp( title: 'Dependency Injection', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( body: HomeView(), ), ), ); } }
The flutter tutorial is a website that bring you the latest and amazing resources of code. All the languages codes are included in this website. The languages like flutter, android, java,kotlin etc.with the help of this languages any user can develop the beautiful application
For more information about Flutter. visit www.fluttertutorial.in