-
-
Notifications
You must be signed in to change notification settings - Fork 153
What's the purpose of dependsOn
?
#391
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
Comments
Check out if https://blog.burkharts.net/lets-get-this-party-started-startup-orchestration-with-getit
Helps you further
Cheers
Thomas
Am 14. Nov. 2024, 21:50 +0100 schrieb J.C.Ködel ***@***.***>:
… import 'package:get_it/get_it.dart';
abstract interface class IDep1 {
void doSomething();
}
abstract interface class IDep2 {
void doSomething();
}
final class Dep1 implements IDep1 {
const Dep1(this.dep2);
final IDep2 dep2;
@OverRide
void doSomething() {
print("Dep1 doing something");
dep2.doSomething();
}
}
final class Dep2 implements IDep2 {
const Dep2();
@OverRide
void doSomething() {
print("Dep2 doing something");
}
}
Future<void> main() async {
GetIt.I.registerSingletonWithDependencies<IDep1>(
() => Dep1(GetIt.I<IDep2>()),
dependsOn: [IDep2],
);
GetIt.I.registerSingleton<IDep2>(const Dep2());
await GetIt.I.allReady();
final dep1 = GetIt.I<IDep1>();
dep1.doSomething();
}
Intuitively, this code should work, because IDep1 is deferred (as it is a factory, not an instance), so, since it is called after all the registrations, why the factory is not called only after allReady or when dependsOn types are available?
How registerSingletonWithDependencies is different from registerSingleton?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
The problem is: I'm not talking about initialization at all! I'm talking about one dependency depending on another =) All my dependencies does not require initialization. But I have some dependencies that require other dependencies to be ready (and the exception is thrown on registration, which doesn't make any sense). In my brain, when I see Not initilized! Registered. The only way I can achieve that is using Then, again, what's the purpose of In my case: @override
Widget build(BuildContext context) {
return DependencyContext(
settings: {
"FirebaseOptions": DefaultFirebaseOptions.currentPlatform,
"DefaultThemeSettings": const ThemeSettings(
seedColor: Colors.pink,
themeMode: ThemeMode.system,
fontFamily: "Poppins",
),
},
dependenciesBuilder: (g) {
FirebaseAppProvider.register(g);
FirebaseAnalyticsProvider.register(g);
AnalyticsService.register(g);
DeviceInfoProvider.register(g);
FirebaseAuthProvider.register(g);
NativeHttpProvider.register(g);
Database.register(g);
AuthRepositoryProvider.register(g);
AuthService.register(g);
ThemeService.register(g);
},
scopeName: "Auth",
builder: (context) => const _MainApp(),
);
}
Almost anyone from now on uses Since Finally, None of those requires initialization whatsoever. I just thought What I did was to actually use static void register(GetIt getIt) {
getIt.registerLazySingleton<AnalyticsService>(
() => AnalyticsService._(getIt.get<IAnalyticsProvider>()),
);
} Maybe my mistake was to believe that For me, |
Ok, I m writing from my phone.
Normally the dependencies with normal or lazy singletons can be easily managed by registering them in the correct sequence.
The problem starts when you need an async factory function so you have to ensure that async singletons are completely initialized before you create any singletons that depend on it.
That's what dependsOn is for. It will ensure that the factory function of singleton B is only called when the async factory function of singleton A has completed if B depends on A.
together with the allReady() function it makes it very easy to let your UI wait till all infrastructure is ready
Am 14. Nov. 2024, 23:17 +0100 schrieb J.C.Ködel ***@***.***>:
… The problem is: I'm not talking about initialization at all! I'm talking about one dependency depending on another =)
All my dependencies does not require initialization. But I have some dependencies that require other dependencies to be ready (and the exception is thrown on registration, which doesn't make any sense).
In my brain, when I see registerSingletonWithDependencies(factory, dependsOn), I understand: ok, this will run the factory when all types in dependsOn are registered.
Not initilized! Registered.
The only way I can achieve that is using registerLazySingleton, which will defer the factory until someone actually need that dependency.
Then, again, what's the purpose of dependsOn??? If registerSingletonWithDependencies behave like registerSingleton, running the factory right in the registration, what's the point?
In my case:
@OverRide
Widget build(BuildContext context) {
return DependencyContext(
settings: {
"FirebaseOptions": DefaultFirebaseOptions.currentPlatform,
"DefaultThemeSettings": const ThemeSettings(
seedColor: Colors.pink,
themeMode: ThemeMode.system,
fontFamily: "Poppins",
),
},
dependenciesBuilder: (g) {
FirebaseAppProvider.register(g);
FirebaseAnalyticsProvider.register(g);
AnalyticsService.register(g);
DeviceInfoProvider.register(g);
FirebaseAuthProvider.register(g);
NativeHttpProvider.register(g);
Database.register(g);
AuthRepositoryProvider.register(g);
AuthService.register(g);
ThemeService.register(g);
},
scopeName: "Auth",
builder: (context) => const _MainApp(),
);
}
FirebaseAppProvider should be the first thing instantiated, because it doesn't depend on anyone.
FirebaseAnalyticsProvider and FirebaseAuthProvider should be next, because they depend on FirebaseAppProvider.
AnalyticsService uses FirebaseAnalyticsProvider, so it comes next.
Almost anyone from now on uses AnalyticsService.
Since AuthService uses AnalyticsService, DeviceInfoProvider, FirebaseAuthProvider, Database, NativeHttpProvider and AuthRepositoryProvider, it should run after all those are registered.
Finally, ThemeService depends on AuthService, so it would be the last one registered (i.e.: instantiated in the registration factory).
None of those requires initialization whatsoever.
I just thought dependsOn would allow me to register dependencies in any order and GetIt would create the singletons based on whomever they depend on =\
What I did was to actually use registerLazySingleton to defer all instantiations to a time when GetIt actually has all types registered.
static void register(GetIt getIt) {
getIt.registerLazySingleton<AnalyticsService>(
() => AnalyticsService._(getIt.get<IAnalyticsProvider>()),
);
}
Maybe my mistake was to believe that GetIt.I.allReady() would be some kind of internal builder that will make and lock the dependency tree.
For me, dependsOn still doesn't make any sense =\
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
I expected GetIt to handle it for me automagically through Thanks for the info. |
registerSingletonWithDeoendency is if normal singleton has to wait for an async one as the registerAsync all have an dependsOn, the basic registerSingleton takes directly an instance so it can't wait for anything.
Am 14. Nov. 2024, 23:42 +0100 schrieb J.C.Ködel ***@***.***>:
… > easily managed by registering them in the correct sequence
I expected GetIt to handle it for me automagically through registerSingletonWithDependencies. I didn't realize that is actually registerSingletonWithDependeciesThatNeedInitializationBeforeTheyCanBeUsedSyncInThisCase. The function name was a bit misleading for me ;-)
Thanks for the info.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
Can you please share the part where you are registering?
Am 15. Nov. 2024, 01:32 +0100 schrieb J.C.Ködel ***@***.***>:
… There is something really wrong with this. I'm getting an infinite getAllReady().
What I'm doing is registering all dependencies as registerSingletonAsync because I can't mix async vs not async (an exception is thrown).
Without that change, one async initializer is never ready (even getAllReady() is called).
With all registration as registerSingletonAsync, getAllReady never completes, because the FutureGroup.close is in this state:
_pending = 1
_values is
image.png (view on web)
So, if I use the "correct" registration process, I can't use GetIt.I<Dep>() inside constructors (because they are not registered yet). Mixing async with non async throws exceptions. If I use all of them as registerSingletonAsync, GetIt.I.allReady() never completes =\
I'm not trying to do anything fancy, only the basic of DI: inject dependencies inside other dependencies.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
ping? |
I'm not using get_it anymore. Sorry. |
You are aware that it's not very polite keeping me busy with questions and then this?
Am 17. Nov. 2024, 18:44 +0100 schrieb J.C.Ködel ***@***.***>:
… I'm not using get_it anymore. Sorry.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
Not meant to be rude. Sorry. I just don't have the code anymore. |
Intuitively, this code should work, because
IDep1
is deferred (as it is a factory, not an instance), so, since it is called after all the registrations, why the factory is not called only afterallReady
or whendependsOn
types are available?How
registerSingletonWithDependencies
is different fromregisterSingleton
?The text was updated successfully, but these errors were encountered: