InheritedCoralProviderWidget<T> class
An InheritedWidget wrapper that provides a CoralProvider<T> to descendant widgets in the element tree.
InheritedCoralProviderWidget exposes a strongly-typed provider (CoralProvider<T>)
down the element tree, allowing descendant CorallineBuildContextAware computations
to reactively subscribe via coralOf<T>() or maybeCoralOf<T>().
Design Philosophy & Architectural System Benefits:
Adheres to Flutter's native dependency propagation mechanism. It notifies dependent elements
only when the reference of provider changes (oldWidget.provider != provider).
- Decoupled Layered Architecture: Bridges pure Dart reactive logic (CoralProvider) with Flutter's element tree without coupling business logic to Flutter UI lifecycles.
- Zero Prop-Drilling: Eliminates deep prop-drilling by leveraging Flutter's $O(1)$
dependOnInheritedWidgetOfExactTypeelement tree lookup mechanics. - Automatic Reactive Unwrapping: Downstream components consume state via
coralOf<T>(), which flattens tree updates and inner Coral state changes into a unified stream. - Push-Dirty, Pull-Data Scheduling: Aligns data propagation with Flutter's frame pipeline, preventing unnecessary widget rebuilds and eliminating UI jank.
- 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)]
Architectural Rationale: Why Inherit InheritedWidget & Suppress Rebuilds?
InheritedCoralProviderWidget directly extends Flutter's native InheritedWidget for 4 core reasons:
- $O(1)$ Engine-Level Lookup Performance: Leverages Flutter engine's internal
_inheritedElementsHashMap viadependOnInheritedWidgetOfExactTypefor instant $O(1)$ ancestor lookups. - Zero-Leak Element Lifecycle Safety: Automatically tracks and cleans up child element dependencies
(
removeDependent) when widgets unmount, eliminating ghost memory leaks common in global service locators. - Seamless Ecosystem Compatibility: Effortlessly bridges native Flutter UI context providers (
Theme,MediaQuery) into pure reactive Coral nodes via CorallineBuildContextAware. - Rebuild Suppression Mechanics: In updateShouldNotify, it compares only
oldWidget.provider != provider. When inner data mutates,updateShouldNotifyreturnsfalse, suppressing Flutter's inefficient forced-rebuild notification pipeline and delegating all updates to Coralline's lazy push-dirty pull-data pipeline.
Generic Type Selection Best Practices (Avoiding Type Shadowing):
- Use Strongly-Typed Domain Models:
Tshould 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 forT. 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 withCoralBroadcaster(or setbroadcast: trueonCoralController). 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 usingCoralProvider.data:final staticConfig = AppConfig(apiBaseUrl: 'https://api.example.com'); final singleWidget = CoralProvider.data(staticConfig).toInheritedWidget( child: const MyApp(), ); - Zero Performance Overhead:
CoralProvider.datacreates a lightweight, static snapshot node. Downstream components consume the state viacoralOf<T>()with identical syntax, preserving complete API uniformity if the data becomes dynamic in the future.
AI & Developer Note:
- Convenience Extension: Prefer using
provider.toInheritedWidget(child: ...)extension method for cleaner, fluid syntax.
Example:
final CoralProvider<CounterState> provider = ...;
final widget = InheritedCoralProviderWidget<CounterState>(
provider: provider,
child: const MyApp(),
);
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- ProxyWidget
- InheritedWidget
- InheritedCoralProviderWidget
Constructors
-
InheritedCoralProviderWidget({required CoralProvider<
T> provider, required Widget child, Key? key}) -
const
Properties
- child → Widget
-
The widget below this widget in the tree.
finalinherited
- hashCode → int
-
The hash code for this object.
no setterinherited
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
-
provider
→ CoralProvider<
T> -
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
createElement(
) → InheritedElement -
Inflates this configuration to a concrete instance.
inherited
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
-
updateShouldNotify(
covariant InheritedCoralProviderWidget< T> oldWidget) → bool -
Whether the framework should notify widgets that inherit from this widget.
override
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited