mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
feat(injector): add $provide.decorator
This commit is contained in:
parent
5e4d59adf0
commit
4e3c05b99e
2 changed files with 155 additions and 1 deletions
|
|
@ -251,7 +251,8 @@ function createInjector(modulesToLoad, moduleRegistry) {
|
|||
value('$provide', {
|
||||
service: service,
|
||||
factory: factory,
|
||||
value: value
|
||||
value: value,
|
||||
decorator: decorator
|
||||
});
|
||||
|
||||
loadModule(modulesToLoad);
|
||||
|
|
@ -274,6 +275,18 @@ function createInjector(modulesToLoad, moduleRegistry) {
|
|||
|
||||
function value(name, value) { factory(name, valueFn(value)); }
|
||||
|
||||
function decorator(name, decorFn) {
|
||||
var origProvider = cache['#' + name + providerSuffix];
|
||||
if (!origProvider) throw Error("Can't find provider for: " + name);
|
||||
if (cache['#' + name]) throw Error("Service " + name + " already instantiated, can't decorate!");
|
||||
var orig$get = origProvider.$get;
|
||||
origProvider.$get = function() {
|
||||
var origInstance = $injector.invoke(origProvider, orig$get);
|
||||
return $injector.invoke(null, decorFn, {$delegate: origInstance});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function getService(value) {
|
||||
if (typeof value !== 'string') {
|
||||
throw Error('Service name expected');
|
||||
|
|
|
|||
|
|
@ -280,6 +280,147 @@ describe('injector', function() {
|
|||
}]).get('value')).toEqual('abc');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('decorator', function() {
|
||||
var log, injector;
|
||||
|
||||
beforeEach(function() {
|
||||
log = [];
|
||||
});
|
||||
|
||||
|
||||
it('should be called with the original instance', function() {
|
||||
injector = createInjector([function($provide) {
|
||||
$provide.value('myService', function(val) {
|
||||
log.push('myService:' + val);
|
||||
return 'origReturn';
|
||||
});
|
||||
|
||||
$provide.decorator('myService', function($delegate) {
|
||||
return function(val) {
|
||||
log.push('myDecoratedService:' + val);
|
||||
var origVal = $delegate('decInput');
|
||||
return 'dec+' + origVal;
|
||||
};
|
||||
});
|
||||
}]);
|
||||
|
||||
var out = injector.get('myService')('input');
|
||||
log.push(out);
|
||||
expect(log.join('; ')).
|
||||
toBe('myDecoratedService:input; myService:decInput; dec+origReturn');
|
||||
});
|
||||
|
||||
|
||||
it('should allow multiple decorators to be applied to a service', function() {
|
||||
injector = createInjector([function($provide) {
|
||||
$provide.value('myService', function(val) {
|
||||
log.push('myService:' + val);
|
||||
return 'origReturn';
|
||||
});
|
||||
|
||||
$provide.decorator('myService', function($delegate) {
|
||||
return function(val) {
|
||||
log.push('myDecoratedService1:' + val);
|
||||
var origVal = $delegate('decInput1');
|
||||
return 'dec1+' + origVal;
|
||||
};
|
||||
});
|
||||
|
||||
$provide.decorator('myService', function($delegate) {
|
||||
return function(val) {
|
||||
log.push('myDecoratedService2:' + val);
|
||||
var origVal = $delegate('decInput2');
|
||||
return 'dec2+' + origVal;
|
||||
};
|
||||
});
|
||||
}]);
|
||||
|
||||
var out = injector.get('myService')('input');
|
||||
log.push(out);
|
||||
expect(log).toEqual(['myDecoratedService2:input',
|
||||
'myDecoratedService1:decInput2',
|
||||
'myService:decInput1',
|
||||
'dec2+dec1+origReturn']);
|
||||
});
|
||||
|
||||
|
||||
it('should decorate services with dependencies', function() {
|
||||
injector = createInjector([function($provide) {
|
||||
$provide.value('dep1', 'dependency1');
|
||||
|
||||
$provide.factory('myService', ['dep1', function(dep1) {
|
||||
return function(val) {
|
||||
log.push('myService:' + val + ',' + dep1);
|
||||
return 'origReturn';
|
||||
}
|
||||
}]);
|
||||
|
||||
$provide.decorator('myService', function($delegate) {
|
||||
return function(val) {
|
||||
log.push('myDecoratedService:' + val);
|
||||
var origVal = $delegate('decInput');
|
||||
return 'dec+' + origVal;
|
||||
};
|
||||
});
|
||||
}]);
|
||||
|
||||
var out = injector.get('myService')('input');
|
||||
log.push(out);
|
||||
expect(log.join('; ')).
|
||||
toBe('myDecoratedService:input; myService:decInput,dependency1; dec+origReturn');
|
||||
});
|
||||
|
||||
|
||||
it('should allow for decorators to be injectable', function() {
|
||||
injector = createInjector([function($provide) {
|
||||
$provide.value('dep1', 'dependency1');
|
||||
|
||||
$provide.factory('myService', function() {
|
||||
return function(val) {
|
||||
log.push('myService:' + val);
|
||||
return 'origReturn';
|
||||
}
|
||||
});
|
||||
|
||||
$provide.decorator('myService', function($delegate, dep1) {
|
||||
return function(val) {
|
||||
log.push('myDecoratedService:' + val + ',' + dep1);
|
||||
var origVal = $delegate('decInput');
|
||||
return 'dec+' + origVal;
|
||||
};
|
||||
});
|
||||
}]);
|
||||
|
||||
var out = injector.get('myService')('input');
|
||||
log.push(out);
|
||||
expect(log.join('; ')).
|
||||
toBe('myDecoratedService:input,dependency1; myService:decInput; dec+origReturn');
|
||||
});
|
||||
|
||||
|
||||
it('should complain if the service to be decorated was already instantiated', function() {
|
||||
injector = createInjector([function($provide, $injector) {
|
||||
$provide.value('myService', function(val) {
|
||||
log.push('myService:' + val);
|
||||
return 'origReturn';
|
||||
});
|
||||
|
||||
$injector.get('myService');
|
||||
|
||||
expect(function() {
|
||||
$provide.decorator('myService', function($delegate) {
|
||||
return function(val) {
|
||||
log.push('myDecoratedService:' + val);
|
||||
var origVal = $delegate('decInput');
|
||||
return 'dec+' + origVal;
|
||||
};
|
||||
});
|
||||
}).toThrow("Service myService already instantiated, can't decorate!");
|
||||
}]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue