akserg/angular.dart.ui

Modal has circular dependency

Closed this issue · 8 comments

Modal cause 'Cannot resolve a circular dependency! ...'.

It seem Timeout class used in Modal has Scope in constructor instead of implementing ScopeAware

Hi,

May I see your source code?

Hi,

It is huge application written in angular-dart and angular-dart-ui. You can look at startup log (not very informative) while I try to reproduce issue in simpler example app.


INFO [application_factory] OSS Mobile client started
INFO [application_factory] Dart current locale: en_US
INFO [application_factory] Dart locale set to: en_US
INFO [application_factory] Loading configuration from: data/config.json
INFO [application_factory] Configuration loaded successfully
INFO [nortal.commons.LocaleContextFactory] Loading localized messages from: data/en.json
INFO [nortal.commons.LocaleContextFactory] Loading localized messages from: data/ar.json
INFO [nortal.commons.LocaleContextFactory] Localization configured successfully
INFO [application_factory] Configuration successfull
INFO [application_factory] -------------------------
INFO [application_factory] Running application .....

Cannot resolve a circular dependency! (resolving DirectiveMap -> DirectiveSelectorFactory -> ElementBinderFactory -> ComponentFactory -> ShadowDomComponentFactory -> ViewFactoryCache -> Http -> RootScope -> Object -> PopupService -> Modal -> Timeout -> Scope -> RootScope)

STACKTRACE:
#0 ModuleInjector.getByKey (package:di/src/injector.dart:120:7)
#1 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#2 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#3 ModuleInjector.getByKey (package:di/src/injector.dart:146:38)
#4 ModuleInjector.getByKey (package:di/src/injector.dart:148:38)
#5 ModuleInjector.getByKey (package:di/src/injector.dart:147:38)
#6 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#7 ModuleInjector.getByKey (package:di/src/injector.dart:151:38)
#8 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#9 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#10 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#11 ModuleInjector.getByKey (package:di/src/injector.dart:150:38)
#12 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#13 ModuleInjector.getByKey (package:di/src/injector.dart:148:38)
#14 Application.run.. (package:angular/application.dart:183:58)
#15 _rootRunUnary (dart:async/zone.dart:902)
#16 _ZoneDelegate.runUnary (dart:async/zone.dart:508)
#17 _onRunUnary. (package:angular/core/zone.dart:122:63)
#18 VmTurnZone._onRunBase (package:angular/core/zone.dart:104:16)
#19 _onRunUnary (package:angular/core/zone.dart:122:17)
#20 _CustomZone.runUnary (dart:async/zone.dart:804)
#21 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:484)
#22 _Future._propagateToListeners (dart:async/future_impl.dart:567)
#23 _Future._completeWithValue (dart:async/future_impl.dart:358)
#24 _Future._asyncComplete. (dart:async/future_impl.dart:412)
#25 _rootRun (dart:async/zone.dart:895)
#26 _ZoneDelegate.run (dart:async/zone.dart:501)
#27 _onScheduleMicrotask. (package:angular/core/zone.dart:127:45)
#28 VmTurnZone._finishTurn (package:angular/core/zone.dart:166:34)
#29 VmTurnZone._onRunBase (package:angular/core/zone.dart:111:43)
#30 _onRun (package:angular/core/zone.dart:118:17)
#31 _CustomZone.run (dart:async/zone.dart:796)
#32 VmTurnZone.run (package:angular/core/zone.dart:257:40)
#33 Application.run (package:angular/application.dart:174:22)
#34 main. (http://localhost:8081/app_main.dart:29:11)
#35 _RootZone.runUnary (dart:async/zone.dart:1155)
#36 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:484)
#37 _Future._propagateToListeners (dart:async/future_impl.dart:567)
#38 _Future._completeWithValue (dart:async/future_impl.dart:358)
#39 _Future._asyncComplete. (dart:async/future_impl.dart:412)
#40 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#41 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#42 _handleMutation (dart:html:41819)

Exception: Uncaught Error: Cannot resolve a circular dependency! (resolving AppService -> Domain -> DomainService -> Ajax -> Http -> RootScope -> Object -> PopupService -> Modal -> Timeout -> Scope -> RootScope)
Stack Trace:
#0 ModuleInjector.getByKey (package:di/src/injector.dart:120:7)
#1 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#2 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#3 ModuleInjector.getByKey (package:di/src/injector.dart:146:38)
#4 ModuleInjector.getByKey (package:di/src/injector.dart:148:38)
#5 ModuleInjector.getByKey (package:di/src/injector.dart:147:38)
#6 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#7 ModuleInjector.getByKey (package:di/src/injector.dart:151:38)
#8 ModuleInjector.getByKey (package:di/src/injector.dart:145:38)
#9 ModuleInjector.getByKey (package:di/src/injector.dart:149:38)
#10 ModuleInjector.getByKey (package:di/src/injector.dart:147:38)
#11 ModuleInjector.getByKey (package:di/src/injector.dart:146:38)
#12 Injector.get (package:di/src/injector.dart:37:15)
#13 main. (http://localhost:8081/app_main.dart:32:28)
#14 _RootZone.runUnary (dart:async/zone.dart:1155)
#15 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:484)
#16 _Future._propagateToListeners (dart:async/future_impl.dart:567)
#17 _Future._completeWithValue (dart:async/future_impl.dart:358)
#18 _Future._asyncComplete. (dart:async/future_impl.dart:412)
#19 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#20 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#21 _handleMutation (dart:html:41819)

Does you code generate a 'circular dependency' exception at the moment of bootstrapping the application because of next line in log:
...
INFO [application_factory] Running application .....
...

Or that happens when you open Modal dialog manually later?

While bootstrapping. Here is simplified code starting from main entry point.


void main() {
readConfiguration().then((OssMobileApp app){
Injector inj = applicationFactory()
.addModule(app)
.rootContextType(AppContext)
.run();
});
}

class OssMobileApp extends Module {
OssMobileApp(DomainConfig _domainConfig) {
install(new AnimationModule());
install(new AngularUIModule());
install(new DomainModule(_domainConfig));
install(new OssMobileGui(_domainConfig));
}
}

class OssMobileGui extends Module {
OssMobileGui(DomainConfig _domainConfig) {
// ...
bind(PopupService);
// ...
}
}

class PopupService implements ScopeAware {
Modal _modal;
PopupService(this._domainConfig, this._navigationCtx, this._eventBus, this._modal, this._window);
}

UPDATE:
@Injectable()
class AppContext {
final PopupService _popupService;
AppContext(this.localizationService, this.navigationCtx, this._popupService);
}

Let me move 'scope' away from Timeout constructor and fix unittests. I will
let you know after commit the source code into GitHub.

On 3 February 2015 at 16:20, Andrej Kolic notifications@github.com wrote:

While bootstrapping. Here is simplified code starting from main entry

point.

void main() {
readConfiguration().then((OssMobileApp app){
Injector inj = applicationFactory()
.addModule(app)
.rootContextType(AppContext)
.run();
});
}

class OssMobileApp extends Module {
OssMobileApp(DomainConfig _domainConfig) {
install(new AnimationModule());
install(new AngularUIModule());
install(new DomainModule(_domainConfig));
install(new OssMobileGui(_domainConfig));
}
}

class OssMobileGui extends Module {
OssMobileGui(DomainConfig _domainConfig) {
// ...
bind(PopupService);
// ...
}
}

class PopupService implements ScopeAware {
Modal _modal;
PopupService(this._domainConfig, this._navigationCtx, this._eventBus,
this._modal, this._window);
}


Reply to this email directly or view it on GitHub
#143 (comment)
.

Thank You.

Fixed in 0.6.4
Please confirm.

Confirmed.

It was also bad design from my side - application root context had implicit references to several classes from core that required scope in constructor (Http from angular.core.dom_internal for example).