@@ -100,6 +100,92 @@ with a single page, prefer page‑scoped [`provide`](./state-management.md) over
100100bind.
101101:::
102102
103+ ## Sharing dependencies across modules
104+
105+ Put a dependency that many features need — a config, an HTTP client, a session — in
106+ a ** root‑owned** (path‑less) "core" module, and depend on it ** by type** anywhere.
107+ You never thread it by hand: a feature's own binds, and its page‑scoped
108+ [ ` provide ` ] ( ./state-management.md ) binds, both resolve it from the graph.
109+
110+ ``` dart
111+ // CORE (root-owned): the shared dependency, registered once
112+ final coreModule = createModule(
113+ register: (c) => c.addInstance<ApiConfig>(ApiConfig('https://api.example')),
114+ );
115+
116+ // FEATURE: its OWN bind depends on the core ApiConfig — supplied automatically
117+ final ordersModule = createModule(
118+ path: '/orders',
119+ register: (c) => c
120+ ..add<OrdersGateway>(OrdersGateway.new) // OrdersGateway(ApiConfig) ← from core
121+ ..route('/', child: (ctx, state) => const OrdersPage()),
122+ );
123+
124+ final appModule = createModule(
125+ register: (c) => c
126+ ..module(coreModule) // included once at the root → visible to every feature
127+ ..module(ordersModule), // takes NO parameters; resolves ApiConfig by type
128+ );
129+ ```
130+
131+ You include the shared module ** once at the root** — there is no need to re‑import it
132+ in each feature (simpler than Angular's per‑feature ` SharedModule ` ). Because the binds
133+ are root‑owned, every feature sees them.
134+
135+ :::info Precedence — local shadows the core
136+ If a feature registers its ** own** bind of the same type, that local bind wins; the
137+ core bind is the fallback. So a feature can override a shared default for itself
138+ without affecting the rest of the app.
139+ :::
140+
141+ :::note Requires 7.1.0+
142+ Resolving a core dependency from a feature's ** module‑level** bind needs
143+ flutter_modular ** 7.1.0** (` auto_injector >= 2.2.0 ` ). Page‑scoped ` provide ` binds
144+ resolved the core in earlier versions too.
145+ :::
146+
147+ ## Async bootstrap (Hive, SharedPreferences, a DB connection)
148+
149+ ` register ` is ** synchronous** , but some shared dependencies need an ` await ` to come up
150+ — opening a Hive box, reading ` SharedPreferences ` , connecting a database. The idiom is
151+ to do that ` await ` ** once** , in a builder that * returns the module* , and capture the
152+ ready instances in its closure. ` main ` stays thin and features take no parameters:
153+
154+ ``` dart
155+ Future<Module> buildCoreModule() async {
156+ await Hive.initFlutter();
157+ final box = await Hive.openBox<dynamic>('app'); // awaited once, here
158+ return createModule(
159+ register: (c) => c
160+ // the raw box stays private in the closure — expose the CONTRACT
161+ ..addInstance<SettingsRepository>(HiveSettingsRepository(box)),
162+ );
163+ }
164+
165+ Future<void> main() async {
166+ WidgetsFlutterBinding.ensureInitialized();
167+ final core = await buildCoreModule(); // one await, one instance
168+ runApp(ModularApp(module: buildAppModule(core), child: const AppRoot()));
169+ }
170+
171+ Module buildAppModule(Module core) => createModule(
172+ register: (c) => c
173+ ..module(core) // shared, root-owned — features resolve it by type
174+ ..module(ordersModule), // no parameters threaded in
175+ );
176+ ```
177+
178+ Blocking on the bootstrap once, then registering the * ready* instances with
179+ ` addInstance ` , keeps the rest of the app synchronous — no loading states sprinkled
180+ through your widgets. Combined with cross‑module resolution above, ` ordersModule ` 's
181+ binds resolve ` SettingsRepository ` from the core with ** zero** parameter threading.
182+
183+ :::warning Build the async module once
184+ ` buildCoreModule() ` returns a ** new** module each call, and composition dedups by
185+ identity — so call it ** once** and reference that single instance. Calling it twice
186+ would open the Hive box twice and register two distinct modules.
187+ :::
188+
103189## Next
104190
105191- Bind state to a page's lifecycle → [ State management] ( ./state-management.md )
0 commit comments