{"id":15177471,"url":"https://github.com/dev-cetera/df_di","last_synced_at":"2026-02-26T06:51:10.697Z","repository":{"id":255438215,"uuid":"849391040","full_name":"dev-cetera/df_di","owner":"dev-cetera","description":"A pragmatic dependency injection (DI) system, coupled with service classes for seamless state management in Dart.","archived":false,"fork":false,"pushed_at":"2026-02-11T09:13:43.000Z","size":1103,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-23T06:57:40.878Z","etag":null,"topics":["dart","dependency-injection","di","flutter","get-it","library","package","services","state","state-management"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/df_di","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dev-cetera.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["robmllze","dev-cetera"],"patreon":"RobertMollentze"}},"created_at":"2024-08-29T14:07:44.000Z","updated_at":"2026-02-11T09:13:47.000Z","dependencies_parsed_at":"2025-01-01T05:19:28.269Z","dependency_job_id":"84d6acb0-8d6e-446d-8064-418ed278f854","html_url":"https://github.com/dev-cetera/df_di","commit_stats":{"total_commits":102,"total_committers":2,"mean_commits":51.0,"dds":"0.13725490196078427","last_synced_commit":"fd94f108a5c0274157f60b9ff8d8541b57a8ae69"},"previous_names":["robmllze/df_di","dev-cetera/df_di","devcetra/df_di"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/dev-cetera/df_di","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cetera%2Fdf_di","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cetera%2Fdf_di/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cetera%2Fdf_di/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cetera%2Fdf_di/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dev-cetera","download_url":"https://codeload.github.com/dev-cetera/df_di/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cetera%2Fdf_di/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29851011,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-25T22:37:40.667Z","status":"online","status_checked_at":"2026-02-26T02:00:06.774Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dependency-injection","di","flutter","get-it","library","package","services","state","state-management"],"created_at":"2024-09-27T14:22:56.933Z","updated_at":"2026-02-26T06:51:10.689Z","avatar_url":"https://github.com/dev-cetera.png","language":"Dart","funding_links":["https://github.com/sponsors/robmllze","https://github.com/sponsors/dev-cetera","https://patreon.com/RobertMollentze","https://www.buymeacoffee.com/dev_cetera","https://www.patreon.com/robelator"],"categories":[],"sub_categories":[],"readme":"[![banner](https://github.com/dev-cetera/df_di/blob/v0.15.10/doc/assets/banner.png?raw=true)](https://github.com/dev-cetera)\n\n[![pub](https://img.shields.io/pub/v/df_di.svg)](https://pub.dev/packages/df_di)\n[![tag](https://img.shields.io/badge/Tag-v0.15.10-purple?logo=github)](https://github.com/dev-cetera/df_di/tree/v0.15.10)\n[![buymeacoffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-FFDD00?logo=buy-me-a-coffee\u0026logoColor=black)](https://www.buymeacoffee.com/dev_cetera)\n[![sponsor](https://img.shields.io/badge/Sponsor-grey?logo=github-sponsors\u0026logoColor=pink)](https://github.com/sponsors/dev-cetera)\n[![patreon](https://img.shields.io/badge/Patreon-grey?logo=patreon)](https://www.patreon.com/robelator)\n[![discord](https://img.shields.io/badge/Discord-5865F2?logo=discord\u0026logoColor=white)](https://discord.gg/gEQ8y2nfyX)\n[![instagram](https://img.shields.io/badge/Instagram-E4405F?logo=instagram\u0026logoColor=white)](https://www.instagram.com/dev_cetera/)\n[![license](https://img.shields.io/badge/License-MIT-blue.svg)](https://raw.githubusercontent.com/dev-cetera/df_di/main/LICENSE)\n\n---\n\n\u003c!-- BEGIN _README_CONTENT --\u003e\n\n`df_di` is a lightweight, powerful \"dependency injection\" package for Dart and Flutter that makes your app modular, testable, and easy to maintain. It stops the confusion of finding and tracking services, like APIs or databases. With `df_di`, you store these services in \"containers\" that make them easy to access whenever you need them.\n\nWhy choose `df_di`? It’s inspired by [get_it](https://pub.dev/packages/get_it) but adds better type safety via monads provided by [df_safer_dart](https://pub.dev/packages/df_safer_dart), more robust async support, better debuggability and a very powerful `until` function that waits for dependencies to be ready, and much more. Whether you’re building a small Flutter app or a large-scale project, `df_di` keeps your code clean and your dependencies accessible.\n\n## Quick Start: Managing a User Service\n\nLet’s dive into a real-world example: managing a `UserService` that fetches user data. This shows how **df_di** containers shine in a Flutter app.\n\n### Step 1: Create a User Service\n\n```dart\nclass UserService {\n  Future\u003cString\u003e getUserName() async {\n    // Simulate fetching user data\n    await Future.delayed(Duration(seconds: 1));\n    return 'Alice';\n  }\n\n  Future\u003cvoid\u003e logOut() async {\n    // Simulate the logout process.\n    await Future.delayed(Duration(seconds: 1));\n  }\n}\n```\n\n### Step 2: Register the Service in a Container\n\nUse a container to store the `UserService`. Here, we’ll put it in `DI.global` for app-wide access.\n\n```dart\nimport 'package:df_di/df_di.dart';\n\nvoid main() {\n  // Register the UserService in the global container\n  DI.global.register\u003cUserService\u003e(\n    UserService(),\n    onUnregister: (result) =\u003e result.unwrap().logOut(),\n  );\n}\n```\n\n- **`DI.global`**: A built-in container for app-wide dependencies.\n- **`register\u003cUserService\u003e`**: Stores the `UserService` instance, tagged by its type.\n\n### Step 3: Access the Service Anywhere\n\nRetrieve the `UserService` from the container and use it in your Flutter widget.\n\n```dart\nimport 'package:flutter/material.dart';\n\nclass UserProfile extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return FutureBuilder\u003cString\u003e(\n      future: DI.global\u003cUserService\u003e().getUserName(),\n      builder: (context, snapshot) {\n        if (snapshot.connectionState == ConnectionState.waiting) {\n          return CircularProgressIndicator();\n        }\n        return Text('Welcome, ${snapshot.data ?? 'Guest'}!');\n      },\n    );\n  }\n}\n```\n\n- **`DI.global\u003cUserService\u003e()`**: Grabs the `UserService` from the container.\n- The widget uses the service to fetch and display the user’s name.\n\nThis is the quick way, but it assumes the service exists. Let’s see a safer approach.\n\n## Step 4: Safe Dependency Access\n\nTo avoid crashes if a dependency is missing, use `getSyncOrNone`:\n\n```dart\nvoid showUser() {\n  final maybeService = DI.global.getSyncOrNone\u003cUserService\u003e();\n  if (maybeService.isSome()) {\n    print('Service found: ${maybeService.unwrap()}');\n  } else {\n    print('No UserService registered.');\n  }\n}\n```\n\n- **`getSyncOrNone\u003cUserService\u003e()`**: Returns `Some\u003cUserService\u003e` if found, or `None` if not.\n- This prevents errors and lets you handle missing dependencies gracefully.\n\n## Step 5: Hierarchical Containers\n\n**df_di**’s containers can form a hierarchy, letting you scope dependencies. Built-in containers include:\n\n- **`DI.global`**: For app-wide services (e.g., `UserService`).\n- **`DI.session`**: For session-specific data (e.g., a logged-in user’s ID).\n- **`DI.user`**: For user-specific data.\n\nChild containers inherit from parents. Here’s an example:\n\n```dart\nvoid setupSession() {\n  // Register a session ID in the session container\n  DI.session.register\u003cString\u003e('session_123');\n\n  // Access it from the user container\n  final sessionId = DI.user\u003cString\u003e();\n  print(sessionId); // Outputs: session_123\n}\n```\n\n- **`DI.user`**: A child of `DI.session`, which is a child of `DI.global`.\n- If `DI.user` doesn’t have a `String`, it checks `DI.session`, then `DI.global`.\n\nYou can also create custom hierarchies:\n\n```dart\nfinal featureContainer = DI();\nfinal screenContainer = DI(parent: featureContainer);\n\nfeatureContainer.register\u003cString\u003e('Feature data');\nprint(screenContainer\u003cString\u003e()); // Outputs: Feature data\n```\n\n## Step 6: Handling Async Dependencies\n\nNeed a dependency that’s not ready yet, like user data from an API? Wait for it with `untilSuper`:\n\n```dart\nFuture\u003cvoid\u003e waitForService() async {\n  // If UserService isn't registered yet, it will just wait until it finds one.\n  // IMPORTANT: When using this function, make sure that XXX in untilSuper\u003cXXX\u003e is the\n  // super-most class or matches the exact type registered. In the case of UserService,\n  // this satisfies the requirement.\n  final service = await DI.global.untilSuper\u003cUserService\u003e().unwrap();\n  print(await service.getUserName()); // Outputs: Alice\n}\n```\n\n- **`untilSuper\u003cUserService\u003e()`**: Waits until a `UserService` is registered in the container or its parents.\n- Perfect for Flutter’s `FutureBuilder` to display data once it’s available.\n\n## Step 7: Lazy Initialization\n\nSave resources by registering dependencies that only create when needed:\n\n```dart\nDI.global.registerConstructor(UserService.new);\n\n// This will create a new instance each time.\nfinal a = DI.global.getLazySingletonSyncOrNone\u003cUserService\u003e(); // Created only now\nfinal b = DI.global.getLazySingletonSyncOrNone\u003cUserService\u003e(); // NOT created again\nprint(a.unwrap() == b.unwrap()); // Outputs: true\n\n// This will create a new instance each time.\nfinal c = DI.global.getLazyFactorySyncOrNone\u003cUserService\u003e();\nfinal d = DI.global.getLazyFactorySyncOrNone\u003cUserService\u003e();\nprint(c.unwrap() == d.unwrap()); // Outputs: false\n```\n\n- **`registerConstructor`**: The `UserService` is built only when first requested.\n\n## Step 8: Cleaning Up\n\nRemove dependencies when they’re no longer needed:\n\n```dart\nDI.session.register\u003cString\u003e('Temporary data');\nDI.session.unregister\u003cString\u003e();\n\nprint(DI.session.isRegistered\u003cString\u003e()); // Outputs: true\n```\n\nYou can also remove all dependencies all at once, i.e. when you log the user out of a session:\n\n```dart\n// This will unregister all dependencies in the reverse order by which they were registered.\nDI.session.unregisterAll();\n```\n\n## Step 9: Service Lifecycle Management\n\n`df_di` includes base service classes with well-defined lifecycle states (init, pause, resume, dispose). These integrate seamlessly with the DI system.\n\n| Class | Purpose |\n|-------|---------|\n| `Service` | Base service with init/pause/resume/dispose lifecycle |\n| `StreamService\u003cTData\u003e` | Service that manages a data stream |\n| `PollingStreamService\u003cTData\u003e` | StreamService that polls at regular intervals |\n\n```dart\nimport 'package:df_di/df_di.dart';\n\n/// A simple counter service with lifecycle management.\nfinal class CounterService extends Service {\n  int _count = 0;\n  int get count =\u003e _count;\n\n  void increment() =\u003e _count++;\n\n  @override\n  TServiceResolvables\u003cUnit\u003e provideInitListeners(void _) =\u003e [\n    (_) {\n      _count = 0;\n      print('CounterService initialized');\n      return syncUnit();\n    },\n  ];\n\n  @override\n  TServiceResolvables\u003cUnit\u003e providePauseListeners(void _) =\u003e [];\n\n  @override\n  TServiceResolvables\u003cUnit\u003e provideResumeListeners(void _) =\u003e [];\n\n  @override\n  TServiceResolvables\u003cUnit\u003e provideDisposeListeners(void _) =\u003e [\n    (_) {\n      print('CounterService disposed with count: $_count');\n      return syncUnit();\n    },\n  ];\n}\n\n// Register with DI and use lifecycle callbacks\nDI.global.register\u003cCounterService\u003e(\n  CounterService(),\n  onRegister: (service) =\u003e service.init(),\n  onUnregister: ServiceMixin.unregister, // Calls dispose() automatically\n);\n\n// Access the service\nfinal counter = DI.global\u003cCounterService\u003e();\ncounter.increment();\n```\n\nFor Flutter apps that need to respond to app lifecycle events (pause when backgrounded, resume when foregrounded), use the `ObservedService` variants from [df_flutter_services](https://pub.dev/packages/df_flutter_services).\n\n## Related Packages\n\n- [df_flutter_services](https://pub.dev/packages/df_flutter_services) - Flutter-specific service classes with app lifecycle integration\n- [df_pod](https://pub.dev/packages/df_pod) - Reactive state containers\n- [df_safer_dart](https://pub.dev/packages/df_safer_dart) - Option, Result, Resolvable types\n\n\u003c!-- END _README_CONTENT --\u003e\n\n---\n\n🔍 For more information, refer to the [API reference](https://pub.dev/documentation/df_di/).\n\n---\n\n## 💬 Contributing and Discussions\n\nThis is an open-source project, and we warmly welcome contributions from everyone, regardless of experience level. Whether you're a seasoned developer or just starting out, contributing to this project is a fantastic way to learn, share your knowledge, and make a meaningful impact on the community.\n\n### ☝️ Ways you can contribute\n\n- **Find us on Discord:** Feel free to ask questions and engage with the community here: https://discord.gg/gEQ8y2nfyX.\n- **Share your ideas:** Every perspective matters, and your ideas can spark innovation.\n- **Help others:** Engage with other users by offering advice, solutions, or troubleshooting assistance.\n- **Report bugs:** Help us identify and fix issues to make the project more robust.\n- **Suggest improvements or new features:** Your ideas can help shape the future of the project.\n- **Help clarify documentation:** Good documentation is key to accessibility. You can make it easier for others to get started by improving or expanding our documentation.\n- **Write articles:** Share your knowledge by writing tutorials, guides, or blog posts about your experiences with the project. It's a great way to contribute and help others learn.\n\nNo matter how you choose to contribute, your involvement is greatly appreciated and valued!\n\n### ☕ We drink a lot of coffee...\n\nIf you're enjoying this package and find it valuable, consider showing your appreciation with a small donation. Every bit helps in supporting future development. You can donate here: https://www.buymeacoffee.com/dev_cetera\n\n\u003ca href=\"https://www.buymeacoffee.com/dev_cetera\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/default-orange.png\" height=\"40\"\u003e\u003c/a\u003e\n\n## LICENSE\n\nThis project is released under the [MIT License](https://raw.githubusercontent.com/dev-cetera/df_di/main/LICENSE). See [LICENSE](https://raw.githubusercontent.com/dev-cetera/df_di/main/LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-cetera%2Fdf_di","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdev-cetera%2Fdf_di","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-cetera%2Fdf_di/lists"}