Skip to content

Conversation

@Hu-Wentao
Copy link
Contributor

This change allows developers to programmatically query the state of a service's underlying ServiceFactory within the container. This is achieved by making the ServiceFactory class and ServiceFactoryType enum public, and by adding a new findFirstFactory method. This enables the creation of more powerful and dynamic tools and frameworks on top of the GetIt platform.

Motivation for Framework and Tool Developers

When building a framework or developer tool on top of GetIt, it's often necessary to understand how a service was registered, not just that it exists. This new API provides that capability, which is valuable for:

  • Lifecycle-aware Logic: A framework can now verify that a service intended for caching is correctly registered as a singleton and provide warnings to the user if it's misconfigured.

  • Dependency Analysis Tools: A developer tool could scan the container, visualize the dependency graph, and label each node with its registration type (singleton, lazySingleton, factory), providing a clear architectural overview.

  • Automatic Validation: A testing framework could automatically assert that services with a specific annotation are registered with an expected lifecycle, reducing boilerplate and enforcing conventions.

Key Changes

  • Exposed ServiceFactory and ServiceFactoryType:

The ServiceFactory abstract class and the ServiceFactoryType enum are now public APIs, allowing them to be used in external code.

  • New GetIt.findFirstFactory Method:

A new method, ServiceFactory? findFirstFactory({String? instanceName}), has been added to the GetIt interface.

It returns the ServiceFactory instance for a given type, allowing access to its .type property and other potential factory state.

Usage Example

// 1. Register a service as a lazy singleton
getIt.registerLazySingleton<ApiService>(() => ApiServiceImpl());

// 2. A framework or tool can now query the factory's state
final factory = getIt.findFirstFactory<ApiService>();

// 3. Execute logic based on the queried state
if (factory != null) {
  print('ApiService factory type: ${factory.type}');
  // -> Expected output: ApiService factory type: ServiceFactoryType.lazySingleton
  
  // Assert that its lifecycle meets framework requirements
  assert(factory.type == ServiceFactoryType.lazySingleton);
} else {
  print('ApiService is not registered.');
}

Copy link
Collaborator

@escamoteur escamoteur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the thing about the redefining of the registration type.
Otherwise I can see how this would be an advantage for tool authors and only exposing an part of the ServiveFactory and not the full class is a good option.
I would be happy to see you on our discussion here https://github.com/orgs/flutter-it/discussions

lib/get_it.dart Outdated
/// for creating an instance when [get] is called
///
/// There are three different types:
typedef ServiceFactoryType = _ServiceFactoryType;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be better to make the enum itself public then instead of redefining it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, but I'm using version 8.0.0-pre-1, and redefining the enum might cause more conflicts when updating older versions.

if (!condition) throw error;
}

const _isDebugMode =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is your format so different? It makes it a bit difficult to diff?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is indeed a mistake. Although I found it before submitting, IDEA may have automatically reformatted the code after submitting.

@escamoteur
Copy link
Collaborator

escamoteur commented Jul 30, 2025 via email

@Hu-Wentao
Copy link
Contributor Author

I'd actually noticed the formatting issue early on and tried to reduce the discrepancies by typedefing ServiceFactoryType.

However, today, using Flutter 3.32.8 (Dart 3.8.1), I reformatted the code using the dart format command, and the indentation discrepancies persisted.

In the end, I manually fixed the discrepancies (the differences weren't as significant as I'd expected).

@Hu-Wentao Hu-Wentao requested a review from escamoteur August 1, 2025 09:08
Copy link
Collaborator

@escamoteur escamoteur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks alot for overhauling the PR.

I was just wondering, if it would make sense to rename findFirstFactory to findFirstRegistration? As it's not only Factories?

What doe you think?

@escamoteur
Copy link
Collaborator

I will merge it but rename ServiceFactory to ObjectRegistration because it makes more sense IMHO

@escamoteur escamoteur changed the base branch from master to rename_service_factory August 2, 2025 18:34
@escamoteur escamoteur merged commit b2122a0 into flutter-it:rename_service_factory Aug 2, 2025
@escamoteur
Copy link
Collaborator

please see #416 includes in V8.2.0

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