New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ioc-service-container

Package Overview
Dependencies
Maintainers
0
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ioc-service-container - npm Package Compare versions

Comparing version 1.6.1 to 2.0.0

2

dist/decorators.js

@@ -27,4 +27,4 @@ "use strict";

get,
set
set,
});
}
import ServiceContainer from './ServiceContainer';
import { inject } from './decorators';
import { scg } from './helpers';
export { ServiceContainer, inject, scg, };
export { ServiceContainer, inject, scg };
declare const _default: {
/**
*
* @param id to identify the service in the container, it can be mapped to a property name via the inject decorator
* @param factoryOrClassReference to create the instance of the service
* @param buildInstantly by default the service is only instantiated on demand, if required you are able to build the service directly
* Register a service in the container
* @param id {string} to identify the service in the container, it can be mapped to a property name via the inject decorator
* @param provider factory, constructable or entity which is stored in the container
*/
set(id: string, factoryOrClassReference: Factory | Function, buildInstantly?: boolean): void;
get<T>(id: string): T;
override(id: string, factoryOrClassReference: Factory | Function, buildInstantly?: boolean): void;
set<T>(id: string, provider: NoUndefined<T>): void;
/**
* Overrides a service in the container. If the service does not exist, it will be registered.
* @param id {string}
* @param provider
*/
override<T_1>(id: string, provider: NoUndefined<T_1>): void;
/**
* Get a service from the container. If the service is not instantiated, it will be instantiated.
* @param id {string}
*/
get<T_2>(id: string): T_2;
/**
* Check if the service is set in the container
* @param id {string}
*/
isSet(id: string): boolean;
/**
* Reset the container
*/
reset(): void;
};
export default _default;
type Factory = () => any;
type NoUndefined<T> = T extends undefined ? never : T;

@@ -6,14 +6,33 @@ "use strict";

/**
*
* @param id to identify the service in the container, it can be mapped to a property name via the inject decorator
* @param factoryOrClassReference to create the instance of the service
* @param buildInstantly by default the service is only instantiated on demand, if required you are able to build the service directly
* Register a service in the container
* @param id {string} to identify the service in the container, it can be mapped to a property name via the inject decorator
* @param provider factory, constructable or entity which is stored in the container
*/
set(id, factoryOrClassReference, buildInstantly = false) {
const lowerId = id.toLowerCase();
if (this.isSet(lowerId)) {
set(id, provider) {
if (this.isSet(id)) {
throw new Error(`Service [${id}] is already registered`);
}
this.override(lowerId, factoryOrClassReference, buildInstantly);
this.override(id, provider);
},
/**
* Overrides a service in the container. If the service does not exist, it will be registered.
* @param id {string}
* @param provider
*/
override(id, provider) {
const lowerId = id.toLowerCase();
if (isConstructable(provider)) {
services[lowerId] = { factory: () => new provider() };
return;
}
if (typeof provider === 'function') {
services[lowerId] = { factory: provider };
return;
}
services[lowerId] = { instance: provider };
},
/**
* Get a service from the container. If the service is not instantiated, it will be instantiated.
* @param id {string}
*/
get(id) {

@@ -25,30 +44,30 @@ var _a;

}
if (!service.instance) {
if (service.instance === undefined) {
service.instance = (_a = service.factory) === null || _a === void 0 ? void 0 : _a.call(service);
service.factory = undefined;
delete service.factory;
}
return service.instance;
},
override(id, factoryOrClassReference, buildInstantly = false) {
const lowerId = id.toLowerCase();
let factory = getFactory(factoryOrClassReference);
services[lowerId] = {
factory: buildInstantly ? undefined : factory,
instance: buildInstantly ? factory() : undefined,
};
},
/**
* Check if the service is set in the container
* @param id {string}
*/
isSet(id) {
return services[id.toLowerCase()] !== undefined;
},
/**
* Reset the container
*/
reset() {
services = {};
}
},
};
function isConstructable(obj) {
return !!obj.prototype && !!obj.prototype.constructor.name;
/**
* Check if the object is a class
* @param value
* @returns {boolean} true if the object is a class
* @see https://stackoverflow.com/a/46320004
*/
function isConstructable(value) {
return typeof value === 'function' && !!value.prototype && !!value.prototype.constructor.name;
}
function getFactory(factoryOrClassReference) {
return isConstructable(factoryOrClassReference)
? () => new factoryOrClassReference()
: factoryOrClassReference;
}
{
"name": "ioc-service-container",
"version": "1.6.1",
"version": "2.0.0",
"description": "Lightweight ioc service container",

@@ -11,3 +11,4 @@ "main": "dist/index.js",

"test": "jest",
"sonar": "sonar-scanner -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=mrcwbr -Dsonar.projectKey=ioc-service-container -Dsonar.sources=src -Dsonar.tests=tests"
"format": "prettier --write .",
"format:check": "prettier . --check"
},

@@ -17,7 +18,7 @@ "author": "mrcwbr",

"devDependencies": {
"@types/jest": "^29.5.3",
"jest": "^29.6.2",
"sonarqube-scanner": "^2.9.1",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"@types/jest": "^29.5.12",
"jest": "^29.7.0",
"prettier": "3.3.3",
"ts-jest": "^29.2.4",
"ts-node": "^10.9.2",
"typescript": "^4.9.5"

@@ -27,4 +28,3 @@ },

"dist/*",
"README.md",
"Changelog.md"
"README.md"
],

@@ -31,0 +31,0 @@ "repository": {

@@ -1,3 +0,5 @@

# ioc-service-container
# IoC Service Container
> This is a lightweight **zero-dependency** library for a service container written in [TypeScript](https://www.typescriptlang.org).
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ioc-service-container&metric=alert_status)](https://sonarcloud.io/dashboard?id=ioc-service-container)

@@ -8,2 +10,3 @@ [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=ioc-service-container&metric=bugs)](https://sonarcloud.io/dashboard?id=ioc-service-container)

[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=ioc-service-container&metric=security_rating)](https://sonarcloud.io/dashboard?id=ioc-service-container)
![min-size](https://badgen.net/bundlephobia/min/ioc-service-container)

@@ -15,25 +18,17 @@ ![min-size-g-zip](https://badgen.net/bundlephobia/minzip/ioc-service-container)

<a href="https://www.buymeacoffee.com/Mrcwbr" target="_blank">
<img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png"
alt="Buy Me A Coffee"
style="height: 41px !important;width: 174px !important;box-shadow: 0 3px 2px 0 rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0 3px 2px 0 rgba(190, 190, 190, 0.5) !important;" >
</a>
> This is a lightweight **zero-dependency** library for a service container written in TypeScript.
## Features
* **Fully typed**
* **100% TypeScript written**
* **100% test coverage**
* **0 dependencies**
* **< 2 KB package size**
* **Typescript Decorator support**
* **Simple API**
* **Works beautiful with [jest-mock-extended](https://www.npmjs.com/package/jest-mock-extended)**
- **Fully typed**
- **100 % [TypeScript](https://www.typescriptlang.org)**
- **100 % Test coverage**
- **0 Dependencies**
- **< 2 KB Package size**
- **[Typescript Decorator](https://www.typescriptlang.org/docs/handbook/decorators.html) support**
- **Simple API**
- **Works beautiful with [jest-mock-extended](https://www.npmjs.com/package/jest-mock-extended)**
## Demo
In this [StackBlitz-Demo](https://stackblitz.com/edit/react-ts-qya4xy?file=App.tsx) you can see a demonstration of
the `ioc-service-container`. In the `App.tsx` you can verify that the `UserService` is fully typed without importing the
In this [StackBlitz-Demo](https://stackblitz.com/edit/react-ts-qya4xy?file=App.tsx) you can see a demonstration of the
`ioc-service-container`. In the `App.tsx` you can verify that the `UserService` is fully typed without importing the
class.

@@ -56,11 +51,12 @@

// Import your services
import { TestApi } from '../your-path/to/TestApi'
import { FooApi } from '../your-path/to/FooApi'
import { TestService } from '../your-path/to/TestService'
import { TestApi } from '../your-path/to/TestApi';
import { FooApi } from '../your-path/to/FooApi';
import { TestService } from '../your-path/to/TestService';
// Create the mapping between ServiceId and Service
type IoCTypes = {
TestApi: TestApi,
FooApi: FooApi,
TestService: TestService,
TestApi: TestApi;
FooApi: FooApi;
TestService: TestService;
myString: string;
// ...

@@ -77,4 +73,4 @@ };

According to this you have to pass a factory or a class reference of your required services to the ioc container. So
at the initial script of your application you call a function named e.g. `setupService`:
According to this you have to pass a factory, a constructable or an entity to the ioc container. So at
the initial script of your application you call a function named e.g. `setupService`:

@@ -87,8 +83,10 @@ ```typescript

ServiceContainer.set('FooApi', () => new CustomFooApi()); // setup by custom factory
ServiceContainer.set('TestService', TestService, true); // instantieate immediately
const testService = new TestService();
ServiceContainer.set('TestService', testService); // pass the instance directly
ServiceContainer.set('myString', 'hello world'); // pass primitive values
}
```
The factory is only instantiated at need. You can pass the `buildInstantly` attribute if the service should be
initialized immediately e.g. for setting up [Sentry](https://sentry.io/welcome/) in a `LoggingService`.
The factory is only instantiated at need.

@@ -107,4 +105,4 @@ ### 3. Inject services

> This requires `"experimentalDecorators": true` to be enabled in your `tsconfig.json`
> (See [Typescript Docs](https://www.typescriptlang.org/tsconfig#experimentalDecorators))
> This requires `"experimentalDecorators": true` to be enabled in your `tsconfig.json` (See
> [Typescript Docs](https://www.typescriptlang.org/tsconfig#experimentalDecorators))

@@ -114,3 +112,3 @@ ```typescript

@inject
private readonly customApi!: Api; // Important is the naming of the property, it's mapped to the service id
private readonly customApi!: Api; // Important is the name of the property, it's mapped to the service id

@@ -120,12 +118,12 @@ @inject('FooApi') // If you don't want to name your property like the service id, pass the id as parameter

private readonly fooApi = ServiceContainer.get<Api>('FooApi') // Use this syntax if you don't want to use decorators
private readonly fooApi = ServiceContainer.get<Api>('FooApi'); // Use this syntax if you don't want to use decorators
private readonly barApi = scg('BarApi') // Shortcut for ServiceContainer.get()
private readonly barApi = scg('BarApi'); // Shortcut for ServiceContainer.get()
}
```
```
### 4. Other Use-Cases
For Testing or similar use cases you have the option to
use `ServiceContainer.isSet('anId')`, `ServiceContainer.override('anId', () => 123)` or `ServiceContainer.reset()`.
For Testing or similar use cases you have the option to use `ServiceContainer.isSet('anId')`,
`ServiceContainer.override('anId', 123)` or `ServiceContainer.reset()`.

@@ -148,2 +146,2 @@ ## Background

The goal of DI is to encapsulate the dependencies of a class. The CustomService should work without knowing which api it
is using. The following structure should be created.
is using.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc