jonsamwell / flutter_simple_dependency_injection

A super simple dependency injection implementation for flutter that behaviours like any normal IOC container and does not rely on mirrors
MIT License
94 stars 8 forks source link

DI not work when use in abstract base state #3

Closed lyquocnam closed 6 years ago

lyquocnam commented 6 years ago

Dear author, in this case, something missing, so it not work fine.

create eventbus:

  injector.map<EventBus>((i) => new EventBus(sync: true));

i have base class like this:

abstract class BaseState<T extends StatefulWidget> extends State<T> {
  final _scaffoldKey = new GlobalKey<ScaffoldState>();

  final _event = injector.get<EventBus>();
  StreamSubscription _sub;

  @override
  void initState() {
    _sub = _event.on<MessageChangedEvent>().listen((event) {
       show(event.message);
    }, onError: (e) {
      print(e);
    }, onDone: () {
      print('done');
    });

      super.initState();
  }

  @override
    void dispose() {
      // TODO: implement dispose
      _sub.cancel();
      super.dispose();
    }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: Text(title()),
      ),
      body: content(),
    );
  }

  void show(String text) {
    _scaffoldKey.currentState.showSnackBar(SnackBar(
      content: Text(text),
    ));
  }

  String title();

  Widget content();

}

and fire event in child class:

class _State extends BaseState<AboutPage> {
  final _event = injector.get<EventBus>();

  // @override
  // void initState() {
  //   super.initState();
  //   _event.on<MessageChangedEvent>().listen((event) {
  //      show(event.message);
  //   });
  // }

  void shout() {
    _event.fire(new MessageChangedEvent('about', MessageType.info));
  }

  @override
  Widget content() {
    return RaisedButton(onPressed: shout, child: Text('login'));
  }

  @override
  String title() {
    return 'About';
  }

}

If i create this case with simple EventBus without DI, it work fine.

// final injector = Injector.getInjector();
final event = new EventBus();

void main() {
  // injector.map<EventBus>((i) => new EventBus());

  runApp(new MyApp());
}

class Service {
  void login() {
    event.fire("Login");
  }
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'KBO - Khám bệnh online',
      theme: new ThemeData.light(),
      home: new TestPage(),
      routes: {
        '/about': (_) => new AboutPage()
      }
    );
  }
}

abstract class BaseState<T extends StatefulWidget> extends State<T> {

  @override
  void initState() {
    super.initState();
    event.on().listen((message) {
      print(message);
    });
  }

}

class TestPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new TestPageState();
  }

}

class TestPageState extends BaseState<TestPage> {
  final _auth = new Service();
  void _show() {
    _auth.login();
  }

  @override
    Widget build(BuildContext context) {
      // TODO: implement build
      return RaisedButton.icon(
        icon: Icon(Icons.clear_all),
        label: Text('Click'),
        onPressed: _show,
      );
    }
}

please see this case in demo project here: https://github.com/lyquocnam/flutter-event

lyquocnam commented 6 years ago

ah... i missing this param when map:

isSingleton: true

omg, it take me a night for this....