63
63
* Implicit module which gets automatically added to each {@link auto.$injector $injector}.
64
64
*/
65
65
66
+ var PROVIDER_ID_SUFFIX = 'Provider' ;
66
67
var ARROW_ARG = / ^ ( [ ^ \( ] + ?) = > / ;
67
68
var FN_ARGS = / ^ [ ^ \( ] * \( \s * ( [ ^ \) ] * ) \) / m;
68
69
var FN_ARG_SPLIT = / , / ;
@@ -129,6 +130,14 @@ function annotate(fn, strictDi, name) {
129
130
return $inject ;
130
131
}
131
132
133
+ function getProviderId ( id ) {
134
+ return ! isString ( id ) ? id : id + PROVIDER_ID_SUFFIX ;
135
+ }
136
+
137
+ function stringifyIdForError ( id , suffix ) {
138
+ return isString ( id ) ? id : id + suffix ;
139
+ }
140
+
132
141
///////////////////////////////////////
133
142
134
143
/**
@@ -647,10 +656,9 @@ function annotate(fn, strictDi, name) {
647
656
function createInjector ( modulesToLoad , strictDi ) {
648
657
strictDi = ( strictDi === true ) ;
649
658
var INSTANTIATING = { } ,
650
- providerSuffix = 'Provider' ,
651
659
path = [ ] ,
652
660
loadedModules = new HashMap ( null , true ) ,
653
- providerCache = {
661
+ providerCache = new HashMap ( {
654
662
$provide : {
655
663
provider : supportObject ( provider ) ,
656
664
factory : supportObject ( factory ) ,
@@ -659,24 +667,22 @@ function createInjector(modulesToLoad, strictDi) {
659
667
constant : supportObject ( constant ) ,
660
668
decorator : decorator
661
669
}
662
- } ,
663
- providerInjector = ( providerCache . $injector =
664
- createInternalInjector ( providerCache , function ( serviceName , caller ) {
665
- if ( angular . isString ( caller ) ) {
666
- path . push ( caller ) ;
667
- }
670
+ } ) ,
671
+ instanceCache = new HashMap ( ) ,
672
+ providerInjector =
673
+ createInternalInjector ( providerCache , function ( serviceName ) {
668
674
throw $injectorMinErr ( 'unpr' , "Unknown provider: {0}" , path . join ( ' <- ' ) ) ;
669
- } ) ) ,
670
- instanceCache = { } ,
675
+ } , ' (provider)' ) ,
671
676
protoInstanceInjector =
672
- createInternalInjector ( instanceCache , function ( serviceName , caller ) {
673
- var provider = providerInjector . get ( serviceName + providerSuffix , caller ) ;
674
- return instanceInjector . invoke (
675
- provider . $get , provider , undefined , serviceName ) ;
677
+ createInternalInjector ( instanceCache , function ( serviceName ) {
678
+ var provider = providerInjector . get ( getProviderId ( serviceName ) ) ;
679
+ return instanceInjector . invoke ( provider . $get , provider ) ;
676
680
} ) ,
677
681
instanceInjector = protoInstanceInjector ;
678
682
679
- providerCache [ '$injector' + providerSuffix ] = { $get : valueFn ( protoInstanceInjector ) } ;
683
+ providerCache . put ( '$injector' , providerInjector ) ;
684
+ providerCache . put ( getProviderId ( '$injector' ) , { $get : valueFn ( protoInstanceInjector ) } ) ;
685
+
680
686
var runBlocks = loadModules ( modulesToLoad ) ;
681
687
instanceInjector = protoInstanceInjector . get ( '$injector' ) ;
682
688
instanceInjector . strictDi = strictDi ;
@@ -690,7 +696,7 @@ function createInjector(modulesToLoad, strictDi) {
690
696
691
697
function supportObject ( delegate ) {
692
698
return function ( key , value ) {
693
- if ( isObject ( key ) ) {
699
+ if ( ( arguments . length === 1 ) && isObject ( key ) ) {
694
700
forEach ( key , reverseParams ( delegate ) ) ;
695
701
} else {
696
702
return delegate ( key , value ) ;
@@ -706,7 +712,10 @@ function createInjector(modulesToLoad, strictDi) {
706
712
if ( ! provider_ . $get ) {
707
713
throw $injectorMinErr ( 'pget' , "Provider '{0}' must define $get factory method." , name ) ;
708
714
}
709
- return ( providerCache [ name + providerSuffix ] = provider_ ) ;
715
+
716
+ providerCache . put ( getProviderId ( name ) , provider_ ) ;
717
+
718
+ return provider_ ;
710
719
}
711
720
712
721
function enforceReturnValue ( name , factory ) {
@@ -737,12 +746,12 @@ function createInjector(modulesToLoad, strictDi) {
737
746
738
747
function constant ( name , value ) {
739
748
assertNotHasOwnProperty ( name , 'constant' ) ;
740
- providerCache [ name ] = value ;
741
- instanceCache [ name ] = value ;
749
+ providerCache . put ( name , value ) ;
750
+ instanceCache . put ( name , value ) ;
742
751
}
743
752
744
753
function decorator ( serviceName , decorFn ) {
745
- var origProvider = providerInjector . get ( serviceName + providerSuffix ) ,
754
+ var origProvider = providerInjector . get ( getProviderId ( serviceName ) ) ,
746
755
orig$get = origProvider . $get ;
747
756
748
757
origProvider . $get = function ( ) {
@@ -805,29 +814,45 @@ function createInjector(modulesToLoad, strictDi) {
805
814
// internal Injector
806
815
////////////////////////////////////
807
816
808
- function createInternalInjector ( cache , factory ) {
817
+ function createInternalInjector ( cache , factory , displayNameSuffix ) {
818
+ if ( ! isString ( displayNameSuffix ) ) {
819
+ displayNameSuffix = '' ;
820
+ }
809
821
810
822
function getService ( serviceName , caller ) {
811
- if ( cache . hasOwnProperty ( serviceName ) ) {
812
- if ( cache [ serviceName ] === INSTANTIATING ) {
813
- throw $injectorMinErr ( 'cdep' , 'Circular dependency found: {0}' ,
814
- serviceName + ' <- ' + path . join ( ' <- ' ) ) ;
815
- }
816
- return cache [ serviceName ] ;
817
- } else {
818
- try {
819
- path . unshift ( serviceName ) ;
820
- cache [ serviceName ] = INSTANTIATING ;
821
- cache [ serviceName ] = factory ( serviceName , caller ) ;
822
- return cache [ serviceName ] ;
823
- } catch ( err ) {
824
- if ( cache [ serviceName ] === INSTANTIATING ) {
825
- delete cache [ serviceName ] ;
823
+ var hasCaller = isDefined ( caller ) ;
824
+ var hadInstance = cache . has ( serviceName ) ;
825
+ var instance ;
826
+
827
+ if ( hasCaller ) {
828
+ path . unshift ( stringifyIdForError ( caller , displayNameSuffix ) ) ;
829
+ }
830
+ path . unshift ( stringifyIdForError ( serviceName , displayNameSuffix ) ) ;
831
+
832
+ try {
833
+ if ( hadInstance ) {
834
+ instance = cache . get ( serviceName ) ;
835
+
836
+ if ( instance === INSTANTIATING ) {
837
+ throw $injectorMinErr ( 'cdep' , 'Circular dependency found: {0}' , path . join ( ' <- ' ) ) ;
826
838
}
827
- throw err ;
828
- } finally {
829
- path . shift ( ) ;
839
+
840
+ return instance ;
841
+ } else {
842
+ cache . put ( serviceName , INSTANTIATING ) ;
843
+
844
+ instance = factory ( serviceName ) ;
845
+ cache . put ( serviceName , instance ) ;
846
+
847
+ return instance ;
848
+ }
849
+ } finally {
850
+ if ( ! hadInstance && ( cache . get ( serviceName ) === INSTANTIATING ) ) {
851
+ cache . remove ( serviceName ) ;
830
852
}
853
+
854
+ path . shift ( ) ;
855
+ if ( hasCaller ) path . shift ( ) ;
831
856
}
832
857
}
833
858
@@ -838,12 +863,8 @@ function createInjector(modulesToLoad, strictDi) {
838
863
839
864
for ( var i = 0 , length = $inject . length ; i < length ; i ++ ) {
840
865
var key = $inject [ i ] ;
841
- if ( typeof key !== 'string' ) {
842
- throw $injectorMinErr ( 'itkn' ,
843
- 'Incorrect injection token! Expected service name as string, got {0}' , key ) ;
844
- }
845
- args . push ( locals && locals . hasOwnProperty ( key ) ? locals [ key ] :
846
- getService ( key , serviceName ) ) ;
866
+ var localsHasKey = locals && isString ( key ) && locals . hasOwnProperty ( key ) ;
867
+ args . push ( localsHasKey ? locals [ key ] : getService ( key , serviceName ) ) ;
847
868
}
848
869
return args ;
849
870
}
@@ -901,7 +922,7 @@ function createInjector(modulesToLoad, strictDi) {
901
922
get : getService ,
902
923
annotate : createInjector . $$annotate ,
903
924
has : function ( name ) {
904
- return providerCache . hasOwnProperty ( name + providerSuffix ) || cache . hasOwnProperty ( name ) ;
925
+ return cache . has ( name ) || providerCache . has ( getProviderId ( name ) ) ;
905
926
}
906
927
} ;
907
928
}
0 commit comments