depend is a library for dependency management in Flutter applications. It provides a convenient way to initialize and access services and repositories via InheritedWidget.
- Dependency Initialization: Prepare all dependencies before the app launches.
- Global Access: Access dependencies from anywhere in the widget tree.
- Parent Dependencies Support: Easily create nested or connected dependencies.
- Ease of Use: Integrate the library into existing code with minimal changes.
- Features 🚀
- Table of Contents
- Installation
- Usage Examples
- Migration Guide
- Code Coverage
Add the library to the pubspec.yaml of your project:
dependencies:
depend: ^latest_versionInstall the dependencies:
flutter pub getCreate a class that extends DependencyContainer and initialize your dependencies:
classRootContainerextendsDependencyContainer {
finalApiService apiService;
RootContainer({requiredthis.apiService});
voiddispose() {
apiService.dispose();
}
}Create a class that extends DependencyContainer and initialize your dependencies:
classRootDependencyFactoryextendsDependencyFactory<RootContainer> {
Future<RootContainer> create() async {
returnRootContainer(
apiService:awaitApiService.initialize(),
);
}
// orRootContainercreate() {
returnRootContainer(
apiService:ApiService.initialize(),
);
}
}Wrap your app in a DependencyScope to provide dependencies:
voidmain() {
runApp(
DependencyScope<RootContainer, RootFactory>(
factory:RootFactory(), placeholder:constCenter(child:CircularProgressIndicator()), builder: (BuildContext context) =>constMyApp(),
),
);
}You can now access the dependency using DependencyProvider anywhere in the widget tree:
classMyWidgetextendsStatelessWidget {
@overrideWidgetbuild(BuildContext context) {
final apiService =DependencyProvider.of<RootContainer>(context).apiService;
returnFutureBuilder(
future: apiService.getData(),
builder: (context, snapshot) {
if (snapshot.connectionState ==ConnectionState.waiting) {
returnconstCircularProgressIndicator();
} elseif (snapshot.hasError) {
returnText('Error: ${snapshot.error}');
}
returnText('Data: ${snapshot.data}');
},
);
}
}finalRootContainer dep =awaitRootFactory().create();
DependencyProvider<RootContainer>(
dependency: dep,
builder: () =>YourWidget();
// or
child:YourWidget()
)
classYourWidgetextendsStatelessWidget {
@overrideWidgetbuild(BuildContext) {
root =DependencyProvider.of<RootContainer>(context);
...
}
}DependencyScope<RootContainer, RootFactory>(
factory:RootFactory(),
builder: (BuildContext context) =>Text('Inject'),
placeholder:Text('Placeholder'),
errorBuilder: (Object? error) =>Text('Error'),
),The library provides LazyGet and LazyFutureGet classes for lazy initialization of services. Dependencies are created only when they are first accessed, which improves application startup time.
classRootContainerextendsDependencyContainer {
// Service will be created only when accessed for the first timefinalLazyGet<ApiService> apiService;
finalLazyGet<DatabaseService> database;
}
classRootDependencyFactoryextendsDependencyFactory<RootContainer> {
RootContainercreate() {
returnRootContainer(
apiService:lazyGet(ApiService.initialize),
database:lazyGet(DatabaseService.initialize),
);
}
}
// Usage in widgetsclassMyWidgetextendsStatelessWidget {
@overrideWidgetbuild(BuildContext context) {
final container =DependencyProvider.of<RootContainer>(context);
// ApiService is created only at this momentfinal api = container.apiService();
returnText('Service initialized: ${api}'); // Instance: ApiService
}
}classRootContainerextendsDependencyContainer {
finalLazyFutureGet<DatabaseService> database;
finalLazyFutureGet<AuthService> authService;
}
classRootDependencyFactoryextendsDependencyFactory<RootContainer> {
RootContainercreate() {
returnRootContainer(
apiService:lazyFutureGet(ApiService.initialize),
database:lazyFutureGet(DatabaseService.initialize),
);
}
}
// Usage in widgetsclassMyWidgetextendsStatelessWidget {
@overrideWidgetbuild(BuildContext context) {
final container =DependencyProvider.of<RootContainer>(context);
returnFutureBuilder<DatabaseService>(
// Database is initialized only when this widget is built
future: container.database(),
builder: (context, snapshot) {
if (snapshot.connectionState ==ConnectionState.waiting) {
returnCircularProgressIndicator();
}
returnText('Database ready: ${snapshot.data?.isConnected}');
},
);
}
}Benefits of Lazy Initialization:
- Faster App Startup: Dependencies are created only when needed
- Memory Optimization: Unused services don't consume memory
- Flexible Initialization: You can control when heavy operations are performed
- Simple API: Easy to use with both sync and async dependencies

