toInheritedWidget method

InheritedCoralProviderWidget<T> toInheritedWidget({
  1. Key? key,
  2. required Widget child,
})

Converts this CoralProvider into an InheritedCoralProviderWidget.

Design Philosophy & Architectural System Benefits:

  1. Decoupled Layered Architecture: Bridges pure Dart reactive logic (CoralProvider) with Flutter's element tree without coupling business logic to Flutter UI lifecycles.
  2. Zero Prop-Drilling: Eliminates deep prop-drilling by leveraging Flutter's $O(1)$ dependOnInheritedWidgetOfExactType element tree lookup mechanics.
  3. Automatic Reactive Unwrapping: Downstream components consume state via coralOf<T>(), which flattens tree updates and inner Coral state changes into a unified stream.
  4. Push-Dirty, Pull-Data Scheduling: Aligns data propagation with Flutter's frame pipeline, preventing unnecessary widget rebuilds and eliminating UI jank.
  5. Lifecycle & Memory Safety: Safely handles hot-swapping and element unmounting without stale context leaks or memory leaks.

System Architectural Flow:

[Business State (CoralProvider<T>)]
       │
       ▼ (toInheritedWidget / Adapting)
[InheritedCoralProviderWidget<T>] (Inject into Flutter Element Tree)
       │
       ▼ (O(1) dependOnInheritedWidgetOfExactType + cascade flattening)
[coralOf<T>()] (Subscribed in downstream CorallineBuildContextAware mixin)
       │
       ▼ (Push-Dirty, Pull-Data)
[UI Rendering (CoralWidget)]

Generic Type Selection Best Practices (Avoiding Type Shadowing):

  • Use Strongly-Typed Domain Models: T should be a unique domain model, store, or state class (e.g., UserStore, CartState, ThemeConfig). Because Flutter looks up InheritedWidget dependencies strictly by exact runtime type, using strongly-typed models guarantees unambiguous element tree resolution.
  • Avoid Primitive Types (int, String, bool): Do not use primitive or generic collection types for T. If multiple primitive providers (e.g., InheritedCoralProviderWidget<String>) exist in the ancestor tree, the lower provider will shadow the upper provider, causing unintended lookup bugs. Wrap primitive values in dedicated domain value objects instead.

Static & Dynamic Injection Strategy (Multi vs Single-Subscriber Rules):

  • Multi-Subscriber Injection (Recommended for Widget Trees): When a provider is injected into the widget tree and multiple descendant components consume coralOf<T>() concurrently, wrap static data with CoralBroadcaster (or set broadcast: true on CoralController). This enables 1:N multi-cast fan-out and prevents single-subscriber ownership collision errors:
    final staticConfig = AppConfig(apiBaseUrl: 'https://api.example.com');
    final appWidget = CoralBroadcaster.data(staticConfig).toInheritedWidget(
      child: const MyApp(),
    );
    
  • Single-Subscriber Injection (Dedicated Single Consumer): If guaranteed that only a single descendant component consumes the state reactively via coralOf<T>(), you can wrap the raw static object directly using CoralProvider.data:
    final staticConfig = AppConfig(apiBaseUrl: 'https://api.example.com');
    final singleWidget = CoralProvider.data(staticConfig).toInheritedWidget(
      child: const MyApp(),
    );
    
  • Zero Performance Overhead: CoralProvider.data creates a lightweight, static snapshot node. Downstream components consume the state via coralOf<T>() with identical syntax, preserving complete API uniformity if the data becomes dynamic in the future.

Use Cases:

  • Global or Feature Dependency Injection: Easily inject reactive stores into the widget tree:
    final userStoreProvider = CoralProvider<UserStore>(...);
    final appWidget = userStoreProvider.toInheritedWidget(child: const MyApp());
    
  • Prop-less Downstream Consumption: Descendant computations consume the state reactively via coralOf without prop-drilling:
    class ProfileDisplay extends ComplexComputation<Widget> with CorallineBuildContextAware {
      late final userStoreCoral = coralOf<UserStore>();
    }
    

Ensures:

Example:

final CoralProvider<CounterState> provider = ...;
final widget = provider.toInheritedWidget(child: const MyApp());

Implementation

InheritedCoralProviderWidget<T> toInheritedWidget(
        {Key? key, required Widget child}) =>
    InheritedCoralProviderWidget<T>(key: key, provider: this, child: child);