{"id":26999865,"url":"https://github.com/jinyus/lite_ref","last_synced_at":"2025-04-04T03:18:07.814Z","repository":{"id":215701510,"uuid":"739592973","full_name":"jinyus/lite_ref","owner":"jinyus","description":"A lightweight dependency injection library for Dart and Flutter.","archived":false,"fork":false,"pushed_at":"2024-11-15T05:51:28.000Z","size":1604,"stargazers_count":12,"open_issues_count":4,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-31T10:04:05.022Z","etag":null,"topics":["dart","dependency-injection","flutter","pubdev"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jinyus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-01-06T00:22:36.000Z","updated_at":"2024-12-01T01:05:35.000Z","dependencies_parsed_at":"2024-01-06T01:31:25.921Z","dependency_job_id":"10fc4e13-ca5b-4b74-ad3d-79671773f5bb","html_url":"https://github.com/jinyus/lite_ref","commit_stats":null,"previous_names":["jinyus/lite_ref"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinyus%2Flite_ref","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinyus%2Flite_ref/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinyus%2Flite_ref/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinyus%2Flite_ref/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jinyus","download_url":"https://codeload.github.com/jinyus/lite_ref/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247112756,"owners_count":20885606,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","flutter","pubdev"],"created_at":"2025-04-04T03:18:07.290Z","updated_at":"2025-04-04T03:18:07.809Z","avatar_url":"https://github.com/jinyus.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg width=\"500\" src=\"https://github.com/jinyus/lite_ref/blob/main/assets/lite_ref_banner.jpg?raw=true\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-MIT-purple\"\u003e \n  \u003ca href=\"https://app.codecov.io/github/jinyus/lite_ref\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/github/jinyus/lite_ref\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pub.dev/packages/lite_ref\"\u003e\u003cimg src=\"https://img.shields.io/pub/points/lite_ref?color=blue\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Overview\n\nLite Ref is a lightweight dependency injection library for Dart and Flutter.\n\n## Installation\n\n```bash\ndart pub add lite_ref\n```\n\n## Why Lite Ref?\n\n-   **Fast**: Doesn't use hashmaps to store instances so it's faster than _all_ other DI libraries.\n-   **Safe**: Uses top level variables so it's impossible to get a NOT_FOUND error.\n-   **Lightweight**: Has no dependencies.\n-   **Simple**: Easy to learn with a small API surface\n\n## Scoped Refs\n\nA `ScopedRef` is a reference that needs a build context to access its instance. This is an alternative to `Provider` for classes that don't rebuild widgets. eg: Controllers, Repositories, Services, etc.\n\n-   Wrap your app or a subtree with a `LiteRefScope`:\n\n    ```dart\n    runApp(\n      LiteRefScope(\n        child: MyApp(),\n      ),\n    );\n    ```\n\n-   Create a `ScopedRef`.\n\n    ```dart\n    final settingsServiceRef = Ref.scoped((ctx) =\u003e SettingsService());\n    ```\n\n-   Access the instance in the current scope:\n\n    This can be done in a widget by using `settingsServiceRef.of(context)` or `settingsServiceRef(context)`.\n\n    ```dart\n    class SettingsPage extends StatelessWidget {\n      const SettingsPage({super.key});\n\n      @override\n      Widget build(BuildContext context) {\n        final settingsService = settingsServiceRef.of(context);\n        return Text(settingsService.getThemeMode());\n      }\n    }\n    ```\n\n-   Override it for a subtree:\n\n    You can override the instance for a subtree by using `overrideWith`. This is useful for testing.\n    In the example below, all calls to `settingsServiceRef.of(context)` will return `MockSettingsService`.\n\n    ```dart\n    LiteRefScope(\n      overrides: {\n        settingsServiceRef.overrideWith((ctx) =\u003e MockSettingsService()),\n      },\n      child: MyApp(),\n    ),\n    ```\n\nA `ScopedFamilyRef` is used when you need to create a unique instance for different keys.\nThis is useful for creating multiple instances of the same class with different configurations.\n\n-   Create a `ScopedFamilyRef`.\n\n    ```dart\n    final postControllerRef = Ref.scopedFamily((ctx, String key) {\n      return PostController(key)..fetch();\n    });\n    ```\n\n-   Access the instance in the current scope:\n\n    This can be done in a widget by using `postController.of(context, key)` or `postController(context, key)`.\n\n    ```dart\n    class PostsPage extends StatelessWidget {\n      const PostsPage({required this.keys, super.key});\n\n      final List\u003cString\u003e keys;\n\n      @override\n      Widget build(BuildContext context) {\n        return ListView.builder(\n          itemBuilder: (context, index) {\n            final post = postControllerRef.of(context, keys[index]);\n            return Text(post?.title ?? 'Loading...');\n          },\n        );\n      }\n    }\n    ```\n\n### Disposal\n\nWhen a `ScopedRef` provides a `ChangeNotifier`, `ValueNotifier` or a class that implements `Disposable`, it will automatically dispose the instance when all the widgets that have access to the instance are unmounted.\n\nIn the example below, the `CounterController` will be disposed when the `CounterView` is unmounted.\n\n```dart\nclass CounterController extends ChangeNotifier {\n  var _count = 0;\n  int get count =\u003e _count;\n\n  void increment() {\n    _count++;\n    notifyListeners();\n  }\n\n  void decrement() {\n    _count--;\n    notifyListeners();\n  }\n}\n\nfinal countControllerRef = Ref.scoped((ctx) =\u003e CounterController());\n\nclass CounterView extends StatelessWidget {\n  const CounterView({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    final controller = countControllerRef.of(context);\n    return ListenableBuilder(\n      listenable: controller,\n      builder: (context, snapshot) {\n        return Text('${controller.count}');\n      },\n    );\n  }\n}\n```\n\n### Click [here](https://github.com/jinyus/lite_ref/tree/main/example/flutter_example) for a flutter example with testing.\n\n## Global Singletons and Transients\n\n-   Create a singleton:\n\n    ```dart\n    final dbRef = Ref.singleton(() =\u003e Database());\n\n    assert(dbRef.instance == dbRef.instance);\n    ```\n\n-   Use it:\n\n    ```dart\n    final db = dbRef.instance; // or dbRef()\n    ```\n\n-   Override it (for testing):\n\n    ```dart\n    dbRef.overrideWith(() =\u003e MockDatabase());\n    ```\n\n-   Freeze it (disable overriding):\n\n    ```dart\n    // overrideWith is marked as @visibleForTesting so this isn't really necessary.\n    dbRef.freeze();\n    ```\n\n-   Create a transient instance (always return new instance):\n\n    ```dart\n    final dbRef = Ref.transient(() =\u003e Database());\n\n    assert(dbRef.instance != dbRef.instance);\n    ```\n\n-   Create a singleton asynchronously:\n\n    ```dart\n    final dbRef = Ref.asyncSingleton(() async =\u003e await Database.init());\n    ```\n\n-   Use it:\n\n    ```dart\n    final db = await dbRef.instance;\n    ```\n\n-   Use it synchronously:\n\n    ```dart\n    // only use this if you know the instance is already created\n    final db = dbRef.assertInstance;\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinyus%2Flite_ref","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjinyus%2Flite_ref","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinyus%2Flite_ref/lists"}