get_it
get_it copied to clipboard
[Question] GetItAll from one type?
Is there any way to get everyone of a kind?
example when logging out of the application I want to get all objects registered as DAO and perform a function of them.
You mean you registered multiple instances of the same type? and you want to call the same method on all of them?
I want get all instance of one type.
Example i have N InterfaceDAO (UserDao, TodoDAO... ) and register all of them.
have some way to resolve all (Iterable<InterfaceDAO>) registered ?
ah, understood. I will think about it.
@escamoteur Have you analyzed this topic? Are there any real chances to implement this?
Could you elaborated why this would be useful?
Of course. Most of all, it helps to write modular and clean code.
For example: I have an Interceptor interface in my http client. In the object responsible for communication with the server, I inject a list of objects implementing the Interceptor interface. Then, when I want to add a new Interceptor, just only create a new implementation.
A similar solution is present in other DI libraries, e.g. Dagger, Spring Boot, etc.
One question would be should it only get all of exact the same type or also derived types?
I think they should it only get all of exact the same type. We can use type passed when there are registering factory, for example
getit.factory<Interceptor>(() => LoggingInterceptor());
Currently, when I register more than one object with the same type and when allowReassignment==false , the library throws an exception. Instead, we could register a collection of interfaces
getit.factory<List<Interceptor>>(() => [
get<LoggingInterceptor>(),
get<AnotherInterceptor>(),
...
]);
Maybe new flag will be necessary to allow binding into collection.
ok, makes sense, but I need to find time for it. Still not finished to convert all my pacakges to null safety
Fantastic :) I haven't explored the get_it internal yet, but in my free time I'll try to help
@escamoteur Hey, have you found the time to focus on this idea? Can we reopen this topic? I believe that this is a crucial and much needed feature
OK,
your PR used a special intoSet parameter. But do we need this if we can use names instances?
You want to be ablt to do a .getAll<Type>() right?
If we limit it to the exact type I would probably only have to make a smal change to the internal get_it data structure. But my feeling is we should be able to request all of one type plus derived types to really allo full flexibility
Yes, I agree that the ability to call derived types should remain.
I have a few ideas, but most of it comes to idea where firstly we register instance in the same way as it is now, and optionally bind it to list of parent types.
Normally we can register instance like this:
getIt.registerFactory(() =>UserDTO())
But if we want to also register instance to collection of supertypes we can call like this:
getIt.registerFactory(() =>UserDTO()).inToList<DTO>();
and in some point in code:
getIt.get<List<DTO>>()
To allow this behavior, each registration method must return an object. An object that allows you to call the inToSet method. An example of this object:
class Multibinding<T extends Object> {
final GetIt _getIt;
Multibinding(this._getIt);
void inToList<S>() {
if (!(T is S)) {
throw "$T is not subtype of $S";
}
if (_getIt.isRegistered<List<S>>()) {
List<S> list = _getIt.get();
_getIt.unregister<List<S>>();
_getIt.registerFactory<List<S>>(() {
T instance = _getIt.get();
var newList = list.toList();
newList.add(instance as S);
return List.unmodifiable(newList);
});
} else {
_getIt.registerFactory<List<S>>(() {
T instance = _getIt.get();
var newList = <S>[];
newList.add(instance as S);
return List.unmodifiable(newList);
});
}
}
}
I think this solution allows you to implement multibinding concept with a minimum amount of work. What do you think?
not sure if we need that.
if we add an
List<MyType> = getIt.getAll<MyType>();
that returns you all registered objects with that type and its derived types.
Hmm.. this will be much better to use.
In this approach when we call getAll<SuperType>(), we need scan all factories and compare like T is SuperType, collect them to list and return.
This will be efficient?
Yeah this might not be very performant. But I try to imagine how often will you have to do such a call? It's probably nothing you do on every frame. it's O(n) which means even if you have registered 1000 objects it shouldn't take long
I would say lets implement it like that and see what the feedback is
would you try a PR?
You're right, maybe it's not such a bad idea. Ok, I will prepare a PR and we will see :)
please don't forget adding the new function to the readme
@mareklat I am working with a similar stuff here, your PR will be very appreciated :D About O(n) problem, I suppose it can be resolved with a getAll<SuperType, DerivadType?>() ?
IMO there is two separate API calls:
getAll<ExactType>()getAllWithSubtypes<SuperType>()
Our practice with Dagger and Guice (Android and backend) shown that first call is sufficient in 90%+ cases. Actually I found 4 cases out of few hundred in all accessible projects where with subtypes lookup is used. For SOLID-complied code that case is very uncommon if possible at all.
So I propose implement '10 for 90' case with just getAll<ExactType>() and see on feedback to implement withSubtypes case.
About O(n) complexity - for most practical graphs (<1000 bindings) is not measurable impact on app performance.
Hi, sorry for not looking into this earlier, but I had some mental health problems the last half year.
No PR has appeared yet. let me see if I find the time to add it
I think a use case like clearing/resetting all the DAOs/ViewModel objects when a user log out can be done by using something like the Pub-Sub pattern instead.
Also let's say I've registered some factories in get it and they all implement IFactory interface. Now I want to write some kind of factory selector and it would be perfect for me to get all factories and then select the appropriate one.
Hey guys, sorry for revive this topic, but is there any plan to implement this feature?
What I really enjoy using Autofac, is how they handle multiple with the As<> binding. You register an instance not only as itself, but also as a specific interface.
Requesting for this interface could return multiple instances or only one.
GetIt.I.register<Foo>(Foo()).As<IFoo>();
GetIt.I.register<Bar>(Bar()).As<IFoo>();
var allFoos = GetIt.I.getAll<IFoo>();
I know that Autofac is a dependency injection framework, but for me something similar could work here as well. I found another package called needle, that seems to do something similar but it hasn't been developed for over 2 years.
The interesting part for me here is that they return some kind of RegistrationBuilder class that again has more functions to work with to complete the registration.
I have not looked into the GetIt code base, but I can imagine that this would require quite some refactor.
What I really enjoy using Autofac, is how they handle multiple with the
As<>binding. You register an instance not only as itself, but also as a specific interface.Requesting for this interface could return multiple instances or only one.
GetIt.I.register<Foo>(Foo()).As<IFoo>(); GetIt.I.register<Bar>(Bar()).As<IFoo>(); var allFoos = GetIt.I.getAll<IFoo>();I know that Autofac is a dependency injection framework, but for me something similar could work here as well. I found another package called needle, that seems to do something similar but it hasn't been developed for over 2 years.
The interesting part for me here is that they return some kind of
RegistrationBuilderclass that again has more functions to work with to complete the registration.I have not looked into the GetIt code base, but I can imagine that this would require quite some refactor.
you are aware, that you can do exactly that if you pass your interface type as the generic parameter?
GetIt.I.register<IFoo>(Bar());
Any movement on this? It's a pretty crucial feature if you want to have a module based architecture
Passing an additional interface type is an interesting idea. Would make it easy to implement it performant. They get_it is currently implemented, getting all implentations of one type wouldn't be fast as I would have to go through all registrations. Passing an optional interface type when registering would be a clear signal to save a reference to that type parallel to the normal registration.
Am 11. Feb. 2024, 18:52 +0100 schrieb James H @.***>:
Any movement on this? It's a pretty crucial feature if you want to support plugins... — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you modified the open/close state.Message ID: @.***>