175 lines
8.2 KiB
Plaintext
175 lines
8.2 KiB
Plaintext
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.BindingManager = void 0;
|
|
const common_1 = require("@inversifyjs/common");
|
|
const core_1 = require("@inversifyjs/core");
|
|
const isBindingIdentifier_1 = require("../../binding/calculations/isBindingIdentifier");
|
|
const BindingFluentSyntaxImplementation_1 = require("../../binding/models/BindingFluentSyntaxImplementation");
|
|
const getFirstIterableResult_1 = require("../../common/calculations/getFirstIterableResult");
|
|
const InversifyContainerError_1 = require("../../error/models/InversifyContainerError");
|
|
const InversifyContainerErrorKind_1 = require("../../error/models/InversifyContainerErrorKind");
|
|
class BindingManager {
|
|
#deactivationParams;
|
|
#defaultScope;
|
|
#planResultCacheManager;
|
|
#serviceReferenceManager;
|
|
constructor(deactivationParams, defaultScope, planResultCacheManager, serviceReferenceManager) {
|
|
this.#deactivationParams = deactivationParams;
|
|
this.#defaultScope = defaultScope;
|
|
this.#planResultCacheManager = planResultCacheManager;
|
|
this.#serviceReferenceManager = serviceReferenceManager;
|
|
}
|
|
bind(serviceIdentifier) {
|
|
return new BindingFluentSyntaxImplementation_1.BindToFluentSyntaxImplementation((binding) => {
|
|
this.#setBinding(binding);
|
|
}, undefined, this.#defaultScope, serviceIdentifier);
|
|
}
|
|
isBound(serviceIdentifier, options) {
|
|
const bindings = this.#serviceReferenceManager.bindingService.get(serviceIdentifier);
|
|
return this.#isAnyValidBinding(serviceIdentifier, bindings, options);
|
|
}
|
|
isCurrentBound(serviceIdentifier, options) {
|
|
const bindings = this.#serviceReferenceManager.bindingService.getNonParentBindings(serviceIdentifier);
|
|
return this.#isAnyValidBinding(serviceIdentifier, bindings, options);
|
|
}
|
|
async rebind(serviceIdentifier) {
|
|
await this.unbind(serviceIdentifier);
|
|
return this.bind(serviceIdentifier);
|
|
}
|
|
rebindSync(serviceIdentifier) {
|
|
this.unbindSync(serviceIdentifier);
|
|
return this.bind(serviceIdentifier);
|
|
}
|
|
async unbind(identifier) {
|
|
await this.#unbind(identifier);
|
|
}
|
|
async unbindAll() {
|
|
const nonParentBoundServiceIds = [
|
|
...this.#serviceReferenceManager.bindingService.getNonParentBoundServices(),
|
|
];
|
|
await Promise.all(nonParentBoundServiceIds.map(async (serviceId) => (0, core_1.resolveServiceDeactivations)(this.#deactivationParams, serviceId)));
|
|
/*
|
|
* Removing service related objects here so unbindAll is deterministic.
|
|
*
|
|
* Removing service related objects as soon as resolveModuleDeactivations takes
|
|
* effect leads to module deactivations not triggering previously deleted
|
|
* deactivations, introducing non determinism depending in the order in which
|
|
* services are deactivated.
|
|
*/
|
|
for (const serviceId of nonParentBoundServiceIds) {
|
|
this.#serviceReferenceManager.activationService.removeAllByServiceId(serviceId);
|
|
this.#serviceReferenceManager.bindingService.removeAllByServiceId(serviceId);
|
|
this.#serviceReferenceManager.deactivationService.removeAllByServiceId(serviceId);
|
|
}
|
|
this.#serviceReferenceManager.planResultCacheService.clearCache();
|
|
}
|
|
unbindSync(identifier) {
|
|
const result = this.#unbind(identifier);
|
|
if (result !== undefined) {
|
|
this.#throwUnexpectedAsyncUnbindOperation(identifier);
|
|
}
|
|
}
|
|
#setBinding(binding) {
|
|
this.#serviceReferenceManager.bindingService.set(binding);
|
|
this.#planResultCacheManager.invalidateService({
|
|
binding: binding,
|
|
kind: core_1.CacheBindingInvalidationKind.bindingAdded,
|
|
});
|
|
}
|
|
#throwUnexpectedAsyncUnbindOperation(identifier) {
|
|
let errorMessage;
|
|
if ((0, isBindingIdentifier_1.isBindingIdentifier)(identifier)) {
|
|
const bindingsById = this.#serviceReferenceManager.bindingService.getById(identifier.id);
|
|
const bindingServiceIdentifier = (0, getFirstIterableResult_1.getFirstIterableResult)(bindingsById)?.serviceIdentifier;
|
|
if (bindingServiceIdentifier === undefined) {
|
|
errorMessage =
|
|
'Unexpected asynchronous deactivation when unbinding binding identifier. Consider using Container.unbind() instead.';
|
|
}
|
|
else {
|
|
errorMessage = `Unexpected asynchronous deactivation when unbinding "${(0, common_1.stringifyServiceIdentifier)(bindingServiceIdentifier)}" binding. Consider using Container.unbind() instead.`;
|
|
}
|
|
}
|
|
else {
|
|
errorMessage = `Unexpected asynchronous deactivation when unbinding "${(0, common_1.stringifyServiceIdentifier)(identifier)}" service. Consider using Container.unbind() instead.`;
|
|
}
|
|
throw new InversifyContainerError_1.InversifyContainerError(InversifyContainerErrorKind_1.InversifyContainerErrorKind.invalidOperation, errorMessage);
|
|
}
|
|
#unbind(identifier) {
|
|
if ((0, isBindingIdentifier_1.isBindingIdentifier)(identifier)) {
|
|
return this.#unbindBindingIdentifier(identifier);
|
|
}
|
|
return this.#unbindServiceIdentifier(identifier);
|
|
}
|
|
#unbindBindingIdentifier(identifier) {
|
|
const bindingsIterable = this.#serviceReferenceManager.bindingService.getById(identifier.id);
|
|
const bindings = bindingsIterable === undefined ? undefined : [...bindingsIterable];
|
|
const result = (0, core_1.resolveBindingsDeactivations)(this.#deactivationParams, bindingsIterable);
|
|
if (result === undefined) {
|
|
this.#clearAfterUnbindBindingIdentifier(bindings, identifier);
|
|
}
|
|
else {
|
|
return result.then(() => {
|
|
this.#clearAfterUnbindBindingIdentifier(bindings, identifier);
|
|
});
|
|
}
|
|
}
|
|
#clearAfterUnbindBindingIdentifier(bindings, identifier) {
|
|
this.#serviceReferenceManager.bindingService.removeById(identifier.id);
|
|
if (bindings !== undefined) {
|
|
for (const binding of bindings) {
|
|
this.#planResultCacheManager.invalidateService({
|
|
binding,
|
|
kind: core_1.CacheBindingInvalidationKind.bindingRemoved,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
#unbindServiceIdentifier(identifier) {
|
|
const bindingsIterable = this.#serviceReferenceManager.bindingService.get(identifier);
|
|
const bindings = bindingsIterable === undefined ? undefined : [...bindingsIterable];
|
|
const result = (0, core_1.resolveBindingsDeactivations)(this.#deactivationParams, bindingsIterable);
|
|
if (result === undefined) {
|
|
this.#clearAfterUnbindServiceIdentifier(identifier, bindings);
|
|
}
|
|
else {
|
|
return result.then(() => {
|
|
this.#clearAfterUnbindServiceIdentifier(identifier, bindings);
|
|
});
|
|
}
|
|
}
|
|
#clearAfterUnbindServiceIdentifier(identifier, bindings) {
|
|
this.#serviceReferenceManager.activationService.removeAllByServiceId(identifier);
|
|
this.#serviceReferenceManager.bindingService.removeAllByServiceId(identifier);
|
|
this.#serviceReferenceManager.deactivationService.removeAllByServiceId(identifier);
|
|
if (bindings !== undefined) {
|
|
for (const binding of bindings) {
|
|
this.#planResultCacheManager.invalidateService({
|
|
binding,
|
|
kind: core_1.CacheBindingInvalidationKind.bindingRemoved,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
#isAnyValidBinding(serviceIdentifier, bindings, options) {
|
|
if (bindings === undefined) {
|
|
return false;
|
|
}
|
|
const bindingConstraints = {
|
|
getAncestor: () => undefined,
|
|
name: options?.name,
|
|
serviceIdentifier,
|
|
tags: new Map(),
|
|
};
|
|
if (options?.tag !== undefined) {
|
|
bindingConstraints.tags.set(options.tag.key, options.tag.value);
|
|
}
|
|
for (const binding of bindings) {
|
|
if (binding.isSatisfiedBy(bindingConstraints)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
exports.BindingManager = BindingManager;
|
|
//# sourceMappingURL=BindingManager.js.map |