Skip to content

Add findAll #407

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

Open
Abion47 opened this issue May 15, 2025 · 0 comments
Open

Add findAll #407

Abion47 opened this issue May 15, 2025 · 0 comments

Comments

@Abion47
Copy link

Abion47 commented May 15, 2025

The existing getAll method returns a list of all services registered under a particular type, but there is not currently a way to get all of the registered services that match a particular type.

The impetus for this issue was this question. While that particular use case would be better resolved using scopes, their naive implementation was to register all of their singletons under a custom Disposable type so they could later use getAll to iterate over them and trigger disposal (not the right way to do this, I know, but stay with me here). The problem with this implementation was that they would have to fetch their services by name and manually cast them to the service type they wanted, which is problematic for several reasons. A "solution" that remained in the spirit of their approach, however, would require a way to query all registered singletons and find the ones that extended Disposable, not just the ones that were registered under Disposable.

A more realistic use case for this might be the following:

abstract interface class IOutput {
  void write(String message);
}

class ConsoleOutput implements IOutput {
  @override
  void write(String message) {
    // Write to console
  }
}

class FileOutput implements IOutput {
  @override
  void write(String message) {
    // Write to local file
  }

  void clearFile() {
    // Truncate local file
  }
}

class RemoteLoggingOutput implements IOutput {
  @override
  void write(String message) {
    // Write to remote logging service
  }

  void setTarget(String url) {
    // Configure the target of the logging service
  }
}

...

void initGetIt() {
  final getIt = GetIt.I;
  
  // Ideal
  getIt.registerSingleton(ConsoleOutput());
  getIt.registerSingleton(FileOutput());
  getIt.registerSingleton(RemoteLoggingOutput());

  // Not ideal for this use case
  getIt.registerSingleton<IOutput>(ConsoleOutput(), instanceName: 'console');
  getIt.registerSingleton<IOutput>(FileOutput(), instanceName: 'file');
  getIt.registerSingleton<IOutput>(RemoteLoggingOutput(), instanceName: 'remoteLogging');
}

Using the first approach, I can access the individual services by type and type safety would be maintained without my needing to worry about getting them by name and casting them to the type I want.

// This is good
GetIt.I.get<FileOutput>().clearFile();
GetIt.I.get<RemoteLoggingOutput>().setTarget('https://api.example.com/log');

// This is verbose and error-prone
(GetIt.I.get<IOutput>(instanceName: 'file') as FileOutput).clearFile();
(GetIt.I.get<IOutput>(instanceName: 'remoteLogging') as RemoteLoggingOutput).setTarget('https://api.example.com/log');

But if I wanted to write something to all of the services, there's no way to do that with the first approach. I would expect to be able to do something like this:

void messageAll(String message) {
  for (final output in GetIt.I.findAll<IOutput>()) {
    output.write(message);
  }
}
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

1 participant