UNPKG

tsioc

Version:

tsioc is AOP, Ioc container, via typescript decorator

443 lines (441 loc) 14.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); require("reflect-metadata"); var types_1 = require("./types"); var Registration_1 = require("./Registration"); var index_1 = require("./utils/index"); var index_2 = require("./aop/index"); var index_3 = require("./core/index"); var index_4 = require("./logs/index"); /** * Container. */ var Container = /** @class */ (function () { function Container() { this.init(); } /** * Retrieves an instance from the container based on the provided token. * * @template T * @param {Token<T>} token * @param {string} [alias] * @param {T} [notFoundValue] * @returns {T} * @memberof Container */ Container.prototype.get = function (token, alias) { return this.resolve(alias ? this.getTokenKey(token, alias) : token); }; /** * resolve type instance with token and param provider. * * @template T * @param {Token<T>} token * @param {T} [notFoundValue] * @param {...Providers[]} providers * @memberof Container */ Container.prototype.resolve = function (token) { var providers = []; for (var _i = 1; _i < arguments.length; _i++) { providers[_i - 1] = arguments[_i]; } var key = this.getTokenKey(token); if (!this.hasRegister(key)) { console.error('have not register', key); return null; } var factory = this.factories.get(key); return factory.apply(void 0, providers); }; /** * clear cache. * * @param {Type<any>} targetType * @memberof IContainer */ Container.prototype.clearCache = function (targetType) { this.get(index_1.symbols.ICacheManager).destroy(targetType); }; /** * get token. * * @template T * @param {Token<T>} token * @param {string} [alias] * @returns {Token<T>} * @memberof Container */ Container.prototype.getToken = function (token, alias) { if (token instanceof Registration_1.Registration) { return token; } else { if (alias && index_1.isFunction(token)) { return new Registration_1.Registration(token, alias); } return token; } }; /** * get tocken key. * * @template T * @param {Token<T>} token * @param {string} [alias] * @returns {SymbolType<T>} * @memberof Container */ Container.prototype.getTokenKey = function (token, alias) { if (token instanceof Registration_1.Registration) { return token.toString(); } else { if (alias) { return new Registration_1.Registration(token, alias).toString(); } return token; } }; /** * register type. * @abstract * @template T * @param {Token<T>} token * @param {T} [value] * @returns {this} * @memberOf Container */ Container.prototype.register = function (token, value) { this.registerFactory(token, value); return this; }; /** * has register the token or not. * * @template T * @param {Token<T>} token * @param {string} [alias] * @returns {boolean} * @memberof Container */ Container.prototype.has = function (token, alias) { var key = this.getTokenKey(token, alias); return this.hasRegister(key); }; /** * has register type. * * @template T * @param {SymbolType<T>} key * @returns * @memberof Container */ Container.prototype.hasRegister = function (key) { return this.factories.has(key); }; /** * unregister the token * * @template T * @param {Token<T>} token * @returns {this} * @memberof Container */ Container.prototype.unregister = function (token) { var key = this.getTokenKey(token); if (this.hasRegister(key)) { this.factories.delete(key); } return this; }; /** * register stingleton type. * @abstract * @template T * @param {Token<T>} token * @param {Factory<T>} [value] * @returns {this} * @memberOf Container */ Container.prototype.registerSingleton = function (token, value) { this.registerFactory(token, value, true); return this; }; /** * bind provider. * * @template T * @param {Token<T>} provide * @param {Token<T>} provider * @returns {this} * @memberof Container */ Container.prototype.bindProvider = function (provide, provider) { var _this = this; var provideKey = this.getTokenKey(provide); var factory; if (index_1.isToken(provider)) { factory = function () { var providers = []; for (var _i = 0; _i < arguments.length; _i++) { providers[_i] = arguments[_i]; } return _this.resolve.apply(_this, [provider].concat(providers)); }; } else { if (index_1.isFunction(provider)) { factory = function () { var providers = []; for (var _i = 0; _i < arguments.length; _i++) { providers[_i] = arguments[_i]; } return provider.apply(void 0, [_this].concat(providers)); }; } else { factory = function () { return provider; }; } } if (index_1.isClass(provider)) { this.provideTypes.set(provide, provider); } else if (index_1.isToken(provider)) { var token = provider; while (this.provideTypes.has(token) && !index_1.isClass(token)) { token = this.provideTypes.get(token); if (index_1.isClass(token)) { this.provideTypes.set(provide, token); break; } } } this.factories.set(provideKey, factory); return this; }; /** * get token implements class type. * * @template T * @param {Token<T>} token * @returns {Type<T>} * @memberof Container */ Container.prototype.getTokenImpl = function (token) { if (index_1.isClass(token)) { return token; } if (this.provideTypes.has(token)) { return this.provideTypes.get(token); } return null; }; /** * get life scope of container. * * @returns {LifeScope} * @memberof IContainer */ Container.prototype.getLifeScope = function () { return this.get(index_1.symbols.LifeScope); }; /** * invoke method async. * * @template T * @param {Token<any>} token * @param {(string | symbol)} propertyKey * @param {*} [instance] * @param {...Providers[]} providers * @returns {Promise<T>} * @memberof Container */ Container.prototype.invoke = function (token, propertyKey, instance) { var providers = []; for (var _i = 3; _i < arguments.length; _i++) { providers[_i - 3] = arguments[_i]; } return (_a = this.get(index_1.symbols.IMethodAccessor)).invoke.apply(_a, [token, propertyKey, instance].concat(providers)); var _a; }; /** * invoke method. * * @template T * @param {Token<any>} token * @param {(string | symbol)} propertyKey * @param {*} [instance] * @param {...Providers[]} providers * @returns {T} * @memberof Container */ Container.prototype.syncInvoke = function (token, propertyKey, instance) { var providers = []; for (var _i = 3; _i < arguments.length; _i++) { providers[_i - 3] = arguments[_i]; } return (_a = this.get(index_1.symbols.IMethodAccessor)).syncInvoke.apply(_a, [token, propertyKey, instance].concat(providers)); var _a; }; Container.prototype.createSyncParams = function (params) { var providers = []; for (var _i = 1; _i < arguments.length; _i++) { providers[_i - 1] = arguments[_i]; } return (_a = this.get(index_1.symbols.IMethodAccessor)).createSyncParams.apply(_a, [params].concat(providers)); var _a; }; Container.prototype.createParams = function (params) { var providers = []; for (var _i = 1; _i < arguments.length; _i++) { providers[_i - 1] = arguments[_i]; } return (_a = this.get(index_1.symbols.IMethodAccessor)).createParams.apply(_a, [params].concat(providers)); var _a; }; Container.prototype.cacheDecorator = function (map, action) { if (!map.has(action.name)) { map.set(action.name, action); } }; Container.prototype.init = function () { var _this = this; this.factories = new index_1.MapSet(); this.singleton = new index_1.MapSet(); this.provideTypes = new index_1.MapSet(); this.bindProvider(index_1.symbols.IContainer, function () { return _this; }); index_3.registerCores(this); index_2.registerAops(this); index_4.registerLogs(this); }; Container.prototype.registerFactory = function (token, value, singleton) { var key = this.getTokenKey(token); if (this.factories.has(key)) { return; } var classFactory; if (!index_1.isUndefined(value)) { if (index_1.isFunction(value)) { if (index_1.isClass(value)) { classFactory = this.createTypeFactory(key, value, singleton); } else { classFactory = this.createCustomFactory(key, value, singleton); } } else if (singleton && value !== undefined) { classFactory = this.createCustomFactory(key, function () { return value; }, singleton); } } else if (!index_1.isString(token) && !index_1.isSymbol(token)) { var ClassT = (token instanceof Registration_1.Registration) ? token.getClass() : token; if (index_1.isClass(ClassT)) { classFactory = this.createTypeFactory(key, ClassT, singleton); } } if (classFactory) { this.factories.set(key, classFactory); } }; Container.prototype.createCustomFactory = function (key, factory, singleton) { var _this = this; return singleton ? function () { var providers = []; for (var _i = 0; _i < arguments.length; _i++) { providers[_i] = arguments[_i]; } if (_this.singleton.has(key)) { return _this.singleton.get(key); } var instance = factory.apply(void 0, [_this].concat(providers)); _this.singleton.set(key, instance); return instance; } : function () { var providers = []; for (var _i = 0; _i < arguments.length; _i++) { providers[_i] = arguments[_i]; } return factory.apply(void 0, [_this].concat(providers)); }; }; Container.prototype.createTypeFactory = function (key, ClassT, singleton) { var _this = this; if (!Reflect.isExtensible(ClassT)) { return null; } var lifeScope = this.getLifeScope(); var parameters = lifeScope.getConstructorParameters(ClassT); if (!singleton) { singleton = lifeScope.isSingletonType(ClassT); } var factory = function () { var providers = []; for (var _i = 0; _i < arguments.length; _i++) { providers[_i] = arguments[_i]; } if (singleton && _this.singleton.has(key)) { return _this.singleton.get(key); } if (providers.length < 1) { var lifecycleData = { targetType: ClassT }; lifeScope.execute(index_3.DecoratorType.Class, lifecycleData, index_3.CoreActions.componentCache); if (lifecycleData.execResult && lifecycleData.execResult instanceof ClassT) { return lifecycleData.execResult; } } lifeScope.execute(index_3.DecoratorType.Class, { targetType: ClassT }, types_1.IocState.runtime); var args = _this.createSyncParams.apply(_this, [parameters].concat(providers)); lifeScope.execute(index_3.DecoratorType.Class, { targetType: ClassT, args: args, params: parameters, providers: providers }, index_3.CoreActions.beforeConstructor); var instance = new (ClassT.bind.apply(ClassT, [void 0].concat(args)))(); lifeScope.execute(index_3.DecoratorType.Class, { target: instance, targetType: ClassT, args: args, params: parameters, providers: providers }, index_3.CoreActions.afterConstructor); lifeScope.execute(index_3.DecoratorType.Property, { target: instance, targetType: ClassT, providers: providers }); lifeScope.execute(index_3.DecoratorType.Method, { target: instance, targetType: ClassT, providers: providers }); if (singleton) { _this.singleton.set(key, instance); } else if (providers.length < 1) { lifeScope.execute(index_3.DecoratorType.Class, { target: instance, targetType: ClassT }, index_3.CoreActions.componentCache); } return instance; }; lifeScope.execute(index_3.DecoratorType.Class, { targetType: ClassT }, types_1.IocState.design); return factory; }; return Container; }()); exports.Container = Container; //# sourceMappingURL=sourcemaps/Container.js.map