ioc_widget 1.0.0 copy "ioc_widget: ^1.0.0" to clipboard
ioc_widget: ^1.0.0 copied to clipboard

A simple, flexible, and testable dependency injection (DI) solution for Flutter, inspired by the best of both the Provider and get_it packages. Supports widget-level DI, transient and singleton strate [...]

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:ioc_widget/ioc_widget.dart';

/// Example class to demonstrate dependency injection.
class ClassA {
  String talk() {
    return "I'm Class A! $hashCode";
  }
}

/// Example class that depends on [ClassA].
class ClassB {
  final ClassA classA;
  const ClassB(this.classA);

  String talk() {
    return "I'm Class B! $hashCode\nAnd I'm Class A! ${classA.hashCode}";
  }
}

/// Example class that depends on [ClassB].
class ClassC {
  final ClassB classB;
  const ClassC(this.classB);

  String talk() {
    return "I'm Class C! $hashCode\n" + classB.talk();
  }
}

void main() {
  runApp(const MyApp());
}

/// Example usage of the IoC widget system with navigation and all public components.
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      initialRoute: '/',
      routes: {
        '/': (_) => const PageA(),
        '/b': (_) => const PageB(),
        '/c': (_) => const PageC(),
      },
      builder:
          (_, child) => MultiIocWidget(
            dependencies: [
              // Register ClassA as a transient (new instance each time)
              InjectableWidget<ClassA>(factory: (_) => ClassA()),
              // Register ClassB as a lazy singleton (same instance for the subtree)
              LazySingletonWidget<ClassB>(factory: (ctx) => ClassB(ctx.get())),
              // Register ClassC as a lazy singleton (to show deeper dependency)
              LazySingletonWidget<ClassC>(factory: (ctx) => ClassC(ctx.get())),
            ],
            child: child!,
          ),
    );
  }
}

class PageA extends StatelessWidget {
  const PageA({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Page A - InjectableWidget')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('ClassA is injected as a transient.'),
            ElevatedButton(
              onPressed: () {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text('ClassA: ${context.get<ClassA>().talk()}'),
                  ),
                );
              },
              child: const Text('Talk (ClassA)'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/b'),
              child: const Text('Go to Page B'),
            ),
          ],
        ),
      ),
    );
  }
}

class PageB extends StatelessWidget {
  const PageB({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Page B - LazySingletonWidget')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('ClassB is injected as a lazy singleton.'),
            ElevatedButton(
              onPressed: () {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text('ClassB: ${context.get<ClassB>().talk()}'),
                  ),
                );
              },
              child: const Text('Talk (ClassB)'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/c'),
              child: const Text('Go to Page C'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Back to Page A'),
            ),
          ],
        ),
      ),
    );
  }
}

class PageC extends StatelessWidget {
  const PageC({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Page C - IocConsumer')),
      body: Center(
        child: IocConsumer<ClassA>(
          builder: (ctx) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text('ClassC is injected using IocConsumer.'),
                ElevatedButton(
                  onPressed: () {
                    ScaffoldMessenger.of(ctx).showSnackBar(
                      SnackBar(
                        content: Text('ClassC: ${ctx.get<ClassC>().talk()}'),
                      ),
                    );
                  },
                  child: const Text('Talk (ClassC)'),
                ),
                ElevatedButton(
                  onPressed: () {
                    ScaffoldMessenger.of(ctx).showSnackBar(
                      SnackBar(
                        content: Text('ClassA: ${ctx.get<ClassA>().talk()}'),
                      ),
                    );
                  },
                  child: const Text('Talk (ClassA)'),
                ),
                ElevatedButton(
                  onPressed: () => Navigator.pop(ctx),
                  child: const Text('Back to Page B'),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}
0
likes
150
points
554
downloads

Publisher

unverified uploader

Weekly Downloads

A simple, flexible, and testable dependency injection (DI) solution for Flutter, inspired by the best of both the Provider and get_it packages. Supports widget-level DI, transient and singleton strategies, and is ideal for scalable, testable, and maintainable Flutter apps.

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on ioc_widget