Problem with Dependency Injection and Get It in Flutter

Viewed 2038

I have been learning about Dependency Injection and now I have implemented an example in dart. But I'm facing an issue with get_it package. Here's the code:

'MessageService.dart'

abstract class MessageService {
  void sendMessage(String msg, String rec);
}

class EmailServiceImpl implements MessageService {
  @override
  void sendMessage(String message, String receiver) {
    //logic to send email
    print("Email sent to $receiver with message $message.");
  }
}

class SMSServiceImpl implements MessageService {
  @override
  void sendMessage(String message, String receiver) {
    //logic to send SMS
    print("SMS sent to $receiver with message $message.");
  }
}
  

'injection_container.dart'

import 'package:get_it/get_it.dart';

import 'MessageService.dart';
import 'main.dart';

final getIt = GetIt.instance;

void init() async {
  getIt.registerFactory<Client>(() => Client());
  getIt.registerFactory<MyApplication>(() => MyApplication(EmailServiceImpl()));
  getIt.registerFactory<MessageService>(() => EmailServiceImpl());
  getIt.registerFactory<MessageService>(() => SMSServiceImpl());
}

'main.dart'

import 'MessageService.dart';
import 'injection_container.dart' as di;

void main() {
  di.init();
  di.getIt<Client>().send();
}

class MyApplication {
  MessageService _service;

  MyApplication(this._service);

  void processMessages(String msg, String rec) {
    //do some msg validation, manipulation logic etc
    this._service.sendMessage(msg, rec);
  }
}

class Client {
  void send() {
    MyApplication app = di.getIt<MyApplication>();
    app.processMessages("Hi Bill", "bill@abc.com");
  }
}

But when registering both EmailServiceImpl and SMSServiceImpl in injection_container.dart it gives me in error as : Unhandled Exception: Invalid argument(s): Object/factory with type MessageService is already registered inside GetIt.

If I comment out SMSServiceImpl registration it works fine. Can someone tell what's the problem? And it would be helpful if someone can review my Dependency Injection example. Is it the right way to present Dependency Injection?

1 Answers

getIt.registerFactory<MessageService>(() => EmailServiceImpl()); getIt.registerFactory<MessageService>(() => SMSServiceImpl());

GetIt only allows (by default) one instance of a type.

So your code is trying to register two instances of a same type (MessageService). From GetIt doc

You have to pass a factory function func that returns an NEW instance of an implementation of T. Each time you call get() you will get a new instance returned.

So when you call GetIt.I.get() it wont know if it's a EmailServiceImpl or a SMSServiceImpl

Try this

getIt.registerFactory<EmailServiceImpl>(() => EmailServiceImpl()); getIt.registerFactory<SMSServiceImpl>(() => SMSServiceImpl());

You can also allow reassingments so your code will work the way it is.

GetIt.I.allowReassignment = true

Related