Skip to content

Allow to register services later in depend on list #154

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
goxiaoy opened this issue Feb 4, 2021 · 15 comments
Closed

Allow to register services later in depend on list #154

goxiaoy opened this issue Feb 4, 2021 · 15 comments

Comments

@goxiaoy
Copy link

goxiaoy commented Feb 4, 2021

I am writing some modularity packages which allows developers to customize each classes by replacing services in DI.
The current implementation check depend on list when register services function is called.

I think it is more reasonable to construct dependency by calling some function like done and DFS the tree for async loading

@escamoteur
Copy link
Collaborator

Not sure what you want to do, but have you seen that you can use the ´signalReadyFunction` to manually handle the async synchronisation?

@goxiaoy
Copy link
Author

goxiaoy commented Feb 4, 2021

considering following cases

in my file

    GetIt.I.allowReassignment = true;
    GetIt.I.registerSingletonAsync<A>(()async{
         var res = AImpl();
         await res.init();
         return res;
     });
    GetIt.I.registerSingletonAsync<B>(()async=>BImpl(),dependsOn: [A]);

and later in user's file to replace A with MyAImpl

    GetIt.I.registerSingletonAsync<A>(()async{
         var res = MyAImpl();
         await res.init();
         return res;
     });

Then B will be loaded incorrectly

@escamoteur
Copy link
Collaborator

you mean because B would still expect AImpl?

@goxiaoy
Copy link
Author

goxiaoy commented Feb 4, 2021

I mean B will not wait until the real MyAImpl is initialized

@escamoteur
Copy link
Collaborator

ok, two questions:

  1. Why do you first register one version of A and then another?
  2. why to you have to register B before you can register the real A that B should wait for? Maybe Scopes could help here.

Even if you need to do it the way you want to you can to that by using manual synchronization.

@goxiaoy
Copy link
Author

goxiaoy commented Feb 4, 2021

For Q1:

Register one version of A and then another is a feature may called Replace in dependency injection. It's can be found in other language's DI system, like C#. It can also be useful in Null object pattern
In my case, I design several packages in layers like API=>Repository=>UI, the api can be adapted from different backend like graphQL, restful api, local database, the repository handles caching and stream, and finally the ui contains the widgets. So for every api class, the default implementation would be InMemoryApiImpl to not break the ui and unit tests

For Q2:
Once you consider the Replace feature, the the meaning of dependOn is that the services container can resolve all these types safely, but not resolve all these types registered before itself

As you can see if there are only few services, manual synchronization would be fine. But once the number grows bigger, it is hard to manage all these sequences

@escamoteur
Copy link
Collaborator

did you checkout get_it scopes?

@goxiaoy
Copy link
Author

goxiaoy commented Feb 4, 2021

Yes, I understand get_it scopes. But it does not affect the dependency load sequence in my case.
I am just thinking that maybe the async register future depend on tree should be construct later when some function like allReady called, but not immediately when being registered

@escamoteur
Copy link
Collaborator

The point why I mention scopes is that the moment you register new types inside the scope (which can also override previous registrations, allReady can be called again. which also means you can just register A & B again when you want to change the implementation.

@escamoteur
Copy link
Collaborator

Also if you change the registraration if A, B will automatically use the latest version from then on. if the new registration of A takes some time you can await it with isReady .

@goxiaoy
Copy link
Author

goxiaoy commented Feb 4, 2021

This works when there are just A and B
But why I need DI is that I get tons of services to be registered 😂

@escamoteur
Copy link
Collaborator

ok, tons of Services, and you want to switch all of the implementations at runtime to different times?
Still struggling to imagine the concrete scenario.

@goxiaoy
Copy link
Author

goxiaoy commented Feb 4, 2021

As a first party package developer, it's easy to change the source code,
But when you want to provide packages for others with customization and combination ability, DI is the way....

Thanks for your patience!
I will close this issue and figure it out by myself 😄

@goxiaoy goxiaoy closed this as completed Feb 4, 2021
@escamoteur
Copy link
Collaborator

If you have a concrete idea how we could support this better perhaps we can do this. But I would need a better understanding for the use case.

@goxiaoy
Copy link
Author

goxiaoy commented Feb 5, 2021

This may be resloved #155 if all futures are scheduled later in allReady

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

2 participants