-
Notifications
You must be signed in to change notification settings - Fork 30.1k
Description
Dart plugin registration uses the implementing-package resolution system described in the federated plugin design doc to figure out which plugins to run Dart registration for. At a high level the rules are:
- If there's a direct dependency from the app on an implementation package, use that (to allow overriding a default implementation).
- Otherwise, use the default implementation.
This works well for normal federated plugin usage. We recently ran into an edge case, which is that sometimes a package might depend only on a specific platform implementation. For example: shared_preference_windows depends directly on path_provider_windows (but not path_provider), because we need the functionality to implement shared_preferences_windows, but we wouldn't want to cause, say, the Android and iOS apps of anything using shared_preferences to unnecessarily include the path_provider code for those platforms. In this case:
- the application has no dependency on the implementation package, and
- there is no default implementation (because the concept of "default implementation" is defined by the app-facing package that we aren't using)
so Dart registration doesn't run forpath_provider_windows. This is fine if we usePathProviderWindowsdirectly (which we do), but breaks if we try to usePathProviderPlatform.instance(which is the equivalent of what the PR above did) for reasons that are probably not at all clear to anyone hit by it.
We have a few options here:
- Keep the current behavior of not running registration
- Run registration for implementation packages whose app-facing packages are not in the transitive dependency list. The question then becomes what to do in the edge case where two different implementations are in the transitive dependency list:
- Pick one of them arbitrarily.
- Error out and require the application that is ultimately the transitive consumer of the two to pick one to depend on.
I'm leaning toward thinking we should do some form of 2 since I would expect the case where two different packages pick two different implementation packages for the same platform to be very rare, so 2 should give surprising behavior less often.