fix(di): instatiate services lazily

This commit is contained in:
vsavkin
2015-07-13 16:28:44 -07:00
parent 2bc1217409
commit 7531b48d02
4 changed files with 207 additions and 76 deletions
@@ -661,17 +661,49 @@ export function main() {
expect(inj.get(NeedsService).service).toEqual('service');
});
it("should not instantiate other directives that depend on viewInjector bindings",
() => {
var directiveAnnotation = new dirAnn.Component({
viewInjector: ListWrapper.concat([bind("service").toValue("service")], extraBindings)
});
var componentDirective =
DirectiveBinding.createFromType(SimpleDirective, directiveAnnotation);
expect(() => { injector([componentDirective, NeedsService], null); })
.toThrowError(containsRegexp(
`No provider for service! (${stringify(NeedsService) } -> service)`));
it("should instantiate hostInjector injectables lazily", () => {
var created = false;
var inj = injector(
ListWrapper.concat([DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component({
hostInjector: [bind('service').toFactory(() => created = true)]
}))],
extraBindings),
null, true);
expect(created).toBe(false);
inj.get('service');
expect(created).toBe(true);
});
it("should instantiate viewInjector injectables lazily", () => {
var created = false;
var inj = injector(
ListWrapper.concat([DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component({
viewInjector: [bind('service').toFactory(() => created = true)]
}))],
extraBindings),
null, true);
expect(created).toBe(false);
inj.get('service');
expect(created).toBe(true);
});
it("should not instantiate other directives that depend on viewInjector bindings",
() => {
var directiveAnnotation = new dirAnn.Component({
viewInjector: ListWrapper.concat([bind("service").toValue("service")], extraBindings)
});
var componentDirective =
DirectiveBinding.createFromType(SimpleDirective, directiveAnnotation);
expect(() => { injector([componentDirective, NeedsService], null); })
.toThrowError(containsRegexp(
`No provider for service! (${stringify(NeedsService) } -> service)`));
});
it("should instantiate directives that depend on hostInjector bindings of other directives", () => {
var shadowInj = hostShadowInjectors(
@@ -1103,6 +1103,32 @@ export function main() {
expect(parent.grandParentBus).toBe(grandParent.bus);
expect(child.bus).toBe(parent.bus);
async.done();
});
}));
it("should create viewInjector injectables lazily",
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new viewAnn.View({
template: `
<component-providing-logging-injectable #providing>
<directive-consuming-injectable *ng-if="ctxBoolProp">
</directive-consuming-injectable>
</component-providing-logging-injectable>
`,
directives:
[DirectiveConsumingInjectable, ComponentProvidingLoggingInjectable, NgIf]
}))
.createAsync(MyComp)
.then((rootTC) => {
var providing = rootTC.componentViewChildren[0].getLocal("providing");
expect(providing.created).toBe(false);
rootTC.componentInstance.ctxBoolProp = true;
rootTC.detectChanges();
expect(providing.created).toBe(true);
async.done();
});
}));
@@ -1701,6 +1727,23 @@ class DirectiveWithTwoWayBinding {
class InjectableService {
}
function createInjectableWithLogging(inj: Injector) {
inj.get(ComponentProvidingLoggingInjectable).created = true;
return new InjectableService();
}
@Component({
selector: 'component-providing-logging-injectable',
hostInjector:
[new Binding(InjectableService, {toFactory: createInjectableWithLogging, deps: [Injector]})]
})
@View({template: ''})
@Injectable()
class ComponentProvidingLoggingInjectable {
created: boolean = false;
}
@Directive({selector: 'directive-providing-injectable', hostInjector: [[InjectableService]]})
@Injectable()
class DirectiveProvidingInjectable {