Skip to content

No type X is registered inside GetIt when used with workmanager package #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
limcheekin opened this issue Aug 17, 2020 · 8 comments
Closed

Comments

@limcheekin
Copy link

limcheekin commented Aug 17, 2020

Hi there,

First of all, many thanks for creating such a great service locator package.

I only face this issue when used get_it with the following workmanager package:
https://pub.dev/packages/workmanager/
More specifically in it's callbackDispatcher method.

Let me show you code snippets to illustrate the issue:

final getIt = GetIt.instance;

getIt.registerLazySingleton<Simple>(() => Simple(10));

await Workmanager.initialize(
    _callbackDispatcher,
    isInDebugMode: true,
 );

The following is code of _callbackDispatcher method:

void _callbackDispatcher() {
  Workmanager.executeTask((task, inputData) async {
    print('$task was executed. inputData = $inputData');
    try {
      print(getIt<Simple>().getCounter());
    } catch (e) {
      print(e);
    }
    return Future.value(true);
  });
}

The following is error print out in the console:

I/flutter (15112): 'package:get_it/get_it_impl.dart': Failed assertion: line 257 pos 14: 'instanceFactory != null': No type Simple is registered inside GetIt.

As the code did registered the Simple instance using registerLazySingleton, I have no idea why the getIt<Simple>() is unable to locate it, any clue?
Appreciate your sharing if you have any idea. Thank in advanced.

By the way, I created the following github repo for you to reproduce the error in your PC:
https://github.com/limcheekin/flutter-getit-workmanager

@escamoteur
Copy link
Collaborator

This is pretty insane. Is looks like that the getIt=GetIt.instance is called twice thus over writing the initialized instance with the registration.

@escamoteur
Copy link
Collaborator

Ok, it looks like that the workmanager creates a separate isolate for the callback that's why it gets its own global variable instances.
You can't use getIt to pass the registered objects to the callback function.

@limcheekin
Copy link
Author

Thanks for quick response.

Isolates is new to me. I might found a solution from workmanager's issues:
fluttercommunity/flutter_workmanager#151 (comment)

And a sample code: https://gist.github.com/lmzach09/147236158999f2e5a5a75e469f9cba3c

@2math
Copy link

2math commented Oct 6, 2020

I don't think is possible to use get_it as to share objects btw both isolates.
On my side when the Workmanager starts it's isolate I have to do same configuration that I have on app start(repository, moor db, shared prefs etc.) and then use them. I can use shared prefs and moor db, but UI isolates can not get the changes until I sent a message on the port and reload prefs and pull from the DB again(streams are not active).
Get_it seems like having access to static objects , which are accessible from it's isolate :(
Btw you may try to parse objects as json and send to the other isolate. But then you will have to invent communication system that will ask and wait for response from other isolate(if is even alive) :)

@limcheekin
Copy link
Author

Thanks for quick response and sharing your experience.

I did the same on define the same (duplicate) configurations that on app start (repository, moor db, shared prefs etc.) and workmanager's callbackDispatcher is the way to go for now, even the solution is not elegant, but it works!

Please update here if you found a better solution, I will do the same. :)

@2math
Copy link

2math commented Oct 7, 2020

Sure I will, but unless workmanager's callbackDispatcher starts shearing same process with our UI isolate we should consider this more or like 2 different applications having access to same app storage.

@elias8
Copy link
Member

elias8 commented Oct 25, 2020

@2math So, did moor work by registering on get_it from different isolates without an issue? That means you will have two different instances of the same database on different isolates, one from the main isolate(main method) and the other from the work manager callback. Is it safe to use that way?

@2math
Copy link

2math commented Oct 27, 2020

@elias8 ,I think you may stuck in situation with "Locked DB", because from both isolates you manipulate same DB file. That is why if you make a change from first isolate the other can see them only if you call get for this data(no streams). I spend a day trying to link the moor DB from 2 isolates, but has no luck. Here is the documentation if you want to try, on success you should have 1 instance of the DB and streams will work on both isolates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants