-
Notifications
You must be signed in to change notification settings - Fork 231
OpaqueToken cannot be implemented in Dart #35
Description
Migrated from angular/angular#8928, but with links refreshed.
Summary: The Angular DI OpaqueToken wrapper class exists solely to create unique token instances, independent of any string argument value that might be provided to the constructor. Given that the OpaqueToken constructor must be const in Dart, and that const constructors are canonicalized, it fails to serve its purpose. In fact, a const constructor that always returns a unique instance cannot be written in Dart.
Details
Each new Angular DI OpaqueToken is meant to be unique. Given that, in Dart, OpaqueTokens are meant to be used in annotations, they must be const; hence the class is defined as follows (note the const constructor):
class OpaqueToken {
final String _desc;
const OpaqueToken(this._desc);
String toString() {
return '''Token ${ this . _desc}''';
}
}But const objects are _canonicalized_ (cf. this commentary in the latex source, or correspondingly, page 68 in the 4th ed. of the spec). Those who might have a doubt can try:
@Component(
selector: 'my-app',
template: "<p>const OpaqueToken('abc') == const OpaqueToken('abc') is {{test}}</p>")
class AppComponent {
final bool test = const OpaqueToken('abc') == const OpaqueToken('abc');
}yields
const OpaqueToken('abc') == const OpaqueToken('abc') is true
Note: since
OpaqueTokendoesn't override==, it uses the one defined inObject, which is true iff the operands areidentical.
This issue came to light during rework of the angular.io DI chapters (for Dart and TS). Issue angular/angular.io#1563 has been opened to hold the thread of discussion of alternatives to OpaqueToken. Once an alternative has been agreed upon, at least for Dart, then OpaqueToken should be deprecated --- given that the Dart implementation is faulty and cannot be fixed, it should just be removed.