Skip to content

Repository files navigation

LogoFrame

Pub VersionLicenseCoverageStars

depend is a library for dependency management in Flutter applications. It provides a convenient way to initialize and access services and repositories via InheritedWidget.


Features 🚀

  • 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.

Table of Contents


Installation

Add the library to the pubspec.yaml of your project:

dependencies:
depend: ^latest_version

Install the dependencies:

flutter pub get

Usage Examples

Example 1: Simple Initialization

Step 1: Define the Dependency

Create a class that extends DependencyContainer and initialize your dependencies:

classRootContainerextendsDependencyContainer {
finalApiService apiService;
RootContainer({requiredthis.apiService});
voiddispose() {
apiService.dispose();
}
}

Step 2: Define the DependencyFactory

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(),
);
}
}

Step 3: Use DependencyScope

Wrap your app in a DependencyScope to provide dependencies:

voidmain() {
runApp(
DependencyScope<RootContainer, RootFactory>(
factory:RootFactory(), placeholder:constCenter(child:CircularProgressIndicator()), builder: (BuildContext context) =>constMyApp(),
),
);
}

Step 4: Access the Dependency in a Widget

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}');
},
);
}
}

Example 2: DependencyProvider

finalRootContainer dep =awaitRootFactory().create();
DependencyProvider<RootContainer>(
dependency: dep,
builder: () =>YourWidget();
// or
child:YourWidget()
)
classYourWidgetextendsStatelessWidget {
@overrideWidgetbuild(BuildContext) {
root =DependencyProvider.of<RootContainer>(context);
...
}
}

Example 3: DependencyScope

DependencyScope<RootContainer, RootFactory>(
factory:RootFactory(),
builder: (BuildContext context) =>Text('Inject'),
placeholder:Text('Placeholder'),
errorBuilder: (Object? error) =>Text('Error'),
),

Example 4: Lazy Initialization

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.

Using LazyGet for Synchronous Dependencies

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
}
}

Using LazyFutureGet for Asynchronous Dependencies

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

Codecov

Codecov

About

dependencies is a Flutter package for managing dependencies and initializing them before the app starts. It provides easy access to dependencies and logs initialization times for performance tracking.

Topics

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages