Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@loveucifer
Copy link

@loveucifer loveucifer commented Oct 27, 2025

No description provided.

@escamoteur
Copy link
Member

Thank You for Your Contribution! 🎉

@loveucifer - Thank you for implementing findAll()! Your PR addresses a long-standing feature request (issues #407, #398, and #75 dating back to 2020!).

We've Enhanced Your Implementation

We've taken your implementation and added powerful enhancements that make it even more useful. This enhanced version will be included in the next get_it release.

What We Added:

1. Type Filtering with includeSubtypes Parameter

List<T> findAll<T>({
  bool includeSubtypes = true,  // NEW!
  bool inAllScopes = false,
  String? onlyInScope,
});

Example:

getIt.registerSingleton<FileOutput>(FileOutput());
getIt.registerSingleton<EnhancedFileOutput>(EnhancedFileOutput()); // extends FileOutput

// Include subtypes (default)
findAll<FileOutput>()  // Returns: [FileOutput, EnhancedFileOutput]

// Exact type only
findAll<FileOutput>(includeSubtypes: false)  // Returns: [FileOutput] only

This uses a clever type trick to check relationships without needing instances:

// Check if T is a subtype of S
bool canBeRetrievedAs<S>() => <T>[] is List<S>;

// Check if T is exactly S (bidirectional)
bool isExactType<S>() => <T>[] is List<S> && <S>[] is List<T>;

2. Comprehensive Scope Control

Three scope search strategies:

// Current scope only (default)
findAll<Disposable>()

// All scopes
findAll<Disposable>(inAllScopes: true)

// Specific named scope
findAll<Disposable>(onlyInScope: 'userSession')

Use case - Scope-specific cleanup:

// Clean up only user session resources
for (final cache in findAll<CacheService>(onlyInScope: 'userSession')) {
  await cache.clear();
}

// Dispose all across all scopes on app shutdown
for (final disposable in findAll<Disposable>(inAllScopes: true)) {
  disposable.dispose();
}

3. Consistency: Added onlyInScope to getAll() and getAllAsync()

For API consistency, we also enhanced the existing methods:

Iterable<T> getAll<T>({
  dynamic param1,
  dynamic param2,
  bool fromAllScopes = false,  // Existing
  String? onlyInScope,         // NEW
});

Key Differences: getAll() vs findAll()

Method Type Checking Returns Use Case
getAll<T>() Registration-type (map lookup) Calls factories, all lazy singletons Get instances registered AS type T
findAll<T>() Runtime type (instance is T) Only instantiated singletons Find instances implementing/extending T

Example:

// Setup
getIt.registerSingleton<FileOutput>(FileOutput());
getIt.registerSingleton<ConsoleOutput>(ConsoleOutput());

// getAll<IOutput>() - ❌ Throws: Nothing registered AS IOutput
// findAll<IOutput>() - ✅ Returns: [FileOutput, ConsoleOutput]

Implementation Status

✅ All 269 existing tests pass
✅ Full documentation added
✅ Scope parameters with mutual exclusivity validation
✅ Type trick avoids need for dart:mirrors

What's Still Needed

Would you like to contribute:

  1. Tests for the new findAll() functionality?
  2. README documentation explaining getAll() vs findAll()?
  3. Example updates showcasing the new parameters?
  4. CHANGELOG entry?

Questions for You

  1. Does this enhanced API meet your original use case?
  2. Any suggestions or concerns about the additions?
  3. Would you like to collaborate on tests/docs?

This will be included in the next get_it release! Thank you for finally making this years-old feature request a reality! 🚀

@loveucifer loveucifer marked this pull request as ready for review October 30, 2025 16:07
@escamoteur escamoteur closed this Oct 30, 2025
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

Successfully merging this pull request may close these issues.

2 participants