chore: npm run format
This commit is contained in:
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Publish
|
||||
env:
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.ACTIONS_PAT }}
|
||||
run: npx semantic-release
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup node
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup node
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
@@ -76,4 +76,3 @@ jobs:
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
|
||||
@@ -52,11 +52,11 @@ Add the following to your `tsconfig.json`:
|
||||
Here's a simple example of how to use netdi:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
ServiceCollection,
|
||||
createServiceIdentifier,
|
||||
injectable,
|
||||
inject
|
||||
import {
|
||||
ServiceCollection,
|
||||
createServiceIdentifier,
|
||||
injectable,
|
||||
inject,
|
||||
} from '@stevanfreeborn/netdi';
|
||||
|
||||
// Define interfaces
|
||||
@@ -82,9 +82,7 @@ class GreetingService implements IGreetingService {
|
||||
|
||||
@injectable()
|
||||
class Greeter implements IGreeter {
|
||||
constructor(
|
||||
@inject(greetingServiceIdentifier) private greetingService: IGreetingService
|
||||
) {}
|
||||
constructor(@inject(greetingServiceIdentifier) private greetingService: IGreetingService) {}
|
||||
|
||||
greet(name: string): string {
|
||||
return this.greetingService.createGreeting(name);
|
||||
@@ -146,14 +144,14 @@ services.addTransient(serviceIdentifier, Implementation);
|
||||
For complex service instantiation, you can use factory methods:
|
||||
|
||||
```typescript
|
||||
services.addSingleton(serviceIdentifier, (provider) => {
|
||||
services.addSingleton(serviceIdentifier, provider => {
|
||||
// Use the provider to get dependencies
|
||||
const dependency = provider.getService(dependencyIdentifier);
|
||||
|
||||
|
||||
// Create and configure your service instance
|
||||
const instance = new MyService(dependency);
|
||||
instance.configure();
|
||||
|
||||
|
||||
return instance;
|
||||
});
|
||||
```
|
||||
@@ -192,7 +190,7 @@ Specifies a dependency for a parameter:
|
||||
class MyService {
|
||||
constructor(
|
||||
@inject(loggerIdentifier) private logger: ILogger,
|
||||
@inject(configIdentifier) private config: IConfig
|
||||
@inject(configIdentifier) private config: IConfig,
|
||||
) {}
|
||||
}
|
||||
```
|
||||
|
||||
+4
-4
@@ -14,11 +14,11 @@ export const DI_INJECTABLE = 'di:injectable';
|
||||
|
||||
/**
|
||||
* Decorator for constructor parameters that specifies which service identifier to use for injection
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to be injected
|
||||
* @param serviceType - The service identifier for the dependency to inject
|
||||
* @returns A parameter decorator function that associates the parameter with the service identifier
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* class MyService {
|
||||
@@ -37,9 +37,9 @@ export function inject<T>(serviceType: ServiceIdentifier<T>): ParameterDecorator
|
||||
|
||||
/**
|
||||
* Decorator that marks a class as injectable, allowing the container to create instances with dependencies
|
||||
*
|
||||
*
|
||||
* @returns A class decorator function that marks the class as injectable
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* @injectable()
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import "reflect-metadata";
|
||||
import 'reflect-metadata';
|
||||
|
||||
export * from './serviceProvider.js';
|
||||
export * from './types.js';
|
||||
|
||||
+19
-18
@@ -11,10 +11,10 @@ import type {
|
||||
|
||||
/**
|
||||
* A collection of service descriptors that can be used to build a service provider.
|
||||
*
|
||||
*
|
||||
* This class is used to register services with different lifetimes and build a service provider
|
||||
* that can resolve those services at runtime.
|
||||
*
|
||||
*
|
||||
* @implements {IServiceCollection}
|
||||
*/
|
||||
export class ServiceCollection implements IServiceCollection {
|
||||
@@ -26,14 +26,14 @@ export class ServiceCollection implements IServiceCollection {
|
||||
|
||||
/**
|
||||
* Registers a singleton service with the collection.
|
||||
*
|
||||
*
|
||||
* Singleton services are created once and shared by all consumers.
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to register
|
||||
* @param serviceType - The service identifier
|
||||
* @param implementationOrFactory - The implementation class or factory function
|
||||
* @returns The service collection instance for method chaining
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* services.addSingleton(userServiceIdentifier, UserService);
|
||||
@@ -50,15 +50,15 @@ export class ServiceCollection implements IServiceCollection {
|
||||
|
||||
/**
|
||||
* Registers a scoped service with the collection.
|
||||
*
|
||||
*
|
||||
* Scoped services are created once per scope. This is useful for services that should be
|
||||
* shared within a request but not across requests.
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to register
|
||||
* @param serviceType - The service identifier
|
||||
* @param implementationOrFactory - The implementation class or factory function
|
||||
* @returns The service collection instance for method chaining
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* services.addScoped(userServiceIdentifier, UserService);
|
||||
@@ -75,14 +75,14 @@ export class ServiceCollection implements IServiceCollection {
|
||||
|
||||
/**
|
||||
* Registers a transient service with the collection.
|
||||
*
|
||||
*
|
||||
* Transient services are created each time they are requested.
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to register
|
||||
* @param serviceType - The service identifier
|
||||
* @param implementationOrFactory - The implementation class or factory function
|
||||
* @returns The service collection instance for method chaining
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* services.addTransient(userServiceIdentifier, UserService);
|
||||
@@ -99,7 +99,7 @@ export class ServiceCollection implements IServiceCollection {
|
||||
|
||||
/**
|
||||
* Builds a service provider from the registered services.
|
||||
*
|
||||
*
|
||||
* @returns A new service provider that can resolve the registered services
|
||||
*/
|
||||
public build(): IServiceProvider {
|
||||
@@ -108,7 +108,7 @@ export class ServiceCollection implements IServiceCollection {
|
||||
|
||||
/**
|
||||
* Internal method to add a service descriptor to the collection.
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to register
|
||||
* @param serviceType - The service identifier
|
||||
* @param implementationOrFactory - The implementation class or factory function
|
||||
@@ -120,7 +120,10 @@ export class ServiceCollection implements IServiceCollection {
|
||||
implementationOrFactory: ServiceFactory<T> | Constructor<T>,
|
||||
lifetime: ServiceLifetime,
|
||||
): IServiceCollection {
|
||||
if (typeof implementationOrFactory === 'function' && this.isConstructor(implementationOrFactory) === false) {
|
||||
if (
|
||||
typeof implementationOrFactory === 'function' &&
|
||||
this.isConstructor(implementationOrFactory) === false
|
||||
) {
|
||||
const descriptor: ServiceDescriptor<T> = {
|
||||
serviceType,
|
||||
implementationType: Object as unknown as Constructor<T>,
|
||||
@@ -144,13 +147,11 @@ export class ServiceCollection implements IServiceCollection {
|
||||
|
||||
/**
|
||||
* Checks if a function is a constructor
|
||||
*
|
||||
*
|
||||
* @param func - The function to check
|
||||
* @returns True if the function is a constructor, false otherwise
|
||||
*/
|
||||
private isConstructor(func: unknown): func is Constructor<unknown> {
|
||||
return typeof func === 'function' &&
|
||||
!!func.prototype &&
|
||||
func.prototype.constructor === func;
|
||||
return typeof func === 'function' && !!func.prototype && func.prototype.constructor === func;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-15
@@ -9,9 +9,9 @@ import type {
|
||||
|
||||
/**
|
||||
* Represents a scope for scoped services.
|
||||
*
|
||||
*
|
||||
* A service scope provides access to scoped services that are created once per scope.
|
||||
*
|
||||
*
|
||||
* @implements {IServiceScope}
|
||||
*/
|
||||
export class ServiceScope implements IServiceScope {
|
||||
@@ -22,7 +22,7 @@ export class ServiceScope implements IServiceScope {
|
||||
|
||||
/**
|
||||
* Creates a new service scope
|
||||
*
|
||||
*
|
||||
* @param serviceProvider - The service provider for this scope
|
||||
*/
|
||||
constructor(serviceProvider: IServiceProvider) {
|
||||
@@ -39,10 +39,10 @@ export class ServiceScope implements IServiceScope {
|
||||
|
||||
/**
|
||||
* A provider that can resolve registered services by their service identifier.
|
||||
*
|
||||
*
|
||||
* The service provider is responsible for creating and managing service instances
|
||||
* according to their registered lifetime.
|
||||
*
|
||||
*
|
||||
* @implements {IServiceProvider}
|
||||
*/
|
||||
export class ServiceProvider implements IServiceProvider {
|
||||
@@ -50,12 +50,12 @@ export class ServiceProvider implements IServiceProvider {
|
||||
* Map of service descriptors by service identifier
|
||||
*/
|
||||
private readonly _descriptors: Map<ServiceIdentifier<unknown>, ServiceDescriptor<unknown>>;
|
||||
|
||||
|
||||
/**
|
||||
* Map of singleton service instances by service identifier
|
||||
*/
|
||||
private readonly _singletonInstances: Map<ServiceIdentifier<unknown>, unknown> = new Map();
|
||||
|
||||
|
||||
/**
|
||||
* Map of scoped service instances by service identifier
|
||||
*/
|
||||
@@ -63,7 +63,7 @@ export class ServiceProvider implements IServiceProvider {
|
||||
|
||||
/**
|
||||
* Creates a new service provider
|
||||
*
|
||||
*
|
||||
* @param descriptors - Map of service descriptors
|
||||
* @param parent - Optional parent service provider to inherit singleton instances from
|
||||
*/
|
||||
@@ -89,12 +89,12 @@ export class ServiceProvider implements IServiceProvider {
|
||||
|
||||
/**
|
||||
* Gets a service instance by its service identifier
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to resolve
|
||||
* @param serviceType - The service identifier of the service to resolve
|
||||
* @returns The resolved service instance
|
||||
* @throws Error if the service is not registered
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const userService = serviceProvider.getService(userServiceIdentifier);
|
||||
@@ -102,7 +102,7 @@ export class ServiceProvider implements IServiceProvider {
|
||||
*/
|
||||
getService<T>(serviceType: ServiceIdentifier<T>): T {
|
||||
const descriptor = this._descriptors.get(serviceType);
|
||||
|
||||
|
||||
if (!descriptor) {
|
||||
throw new Error(`Service of type ${serviceType.toString()} is not registered.`);
|
||||
}
|
||||
@@ -112,9 +112,9 @@ export class ServiceProvider implements IServiceProvider {
|
||||
|
||||
/**
|
||||
* Creates a new scope for scoped services
|
||||
*
|
||||
*
|
||||
* @returns A new service scope
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const scope = serviceProvider.createScope();
|
||||
@@ -137,7 +137,7 @@ export class ServiceProvider implements IServiceProvider {
|
||||
|
||||
/**
|
||||
* Resolves a service instance from its descriptor
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to resolve
|
||||
* @param descriptor - The service descriptor
|
||||
* @returns The resolved service instance
|
||||
@@ -172,7 +172,7 @@ export class ServiceProvider implements IServiceProvider {
|
||||
|
||||
/**
|
||||
* Creates an instance of a service class and resolves its dependencies
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to create
|
||||
* @param ctor - The constructor of the service class
|
||||
* @returns A new instance of the service class with its dependencies resolved
|
||||
|
||||
+49
-34
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Represents the possible lifetimes for registered services
|
||||
*
|
||||
*
|
||||
* - singleton: Created once and shared by all consumers
|
||||
* - scoped: Created once per scope
|
||||
* - transient: Created each time they are requested
|
||||
@@ -9,7 +9,7 @@ export type ServiceLifetime = 'singleton' | 'scoped' | 'transient';
|
||||
|
||||
/**
|
||||
* Represents a constructor function for a class
|
||||
*
|
||||
*
|
||||
* @template T - The type of object the constructor creates
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -17,21 +17,21 @@ export type Constructor<T> = new (...args: any[]) => T;
|
||||
|
||||
/**
|
||||
* A unique identifier for a service type
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
*/
|
||||
export type ServiceIdentifier<T = unknown> = symbol & { __brand: T };
|
||||
|
||||
/**
|
||||
* A factory function that creates a service instance
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to create
|
||||
*/
|
||||
export type ServiceFactory<T> = (provider: IServiceProvider) => T;
|
||||
|
||||
/**
|
||||
* Descriptor for a registered service
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
*/
|
||||
export type ServiceDescriptor<T = unknown> = {
|
||||
@@ -39,17 +39,17 @@ export type ServiceDescriptor<T = unknown> = {
|
||||
* The service identifier
|
||||
*/
|
||||
serviceType: ServiceIdentifier<T>;
|
||||
|
||||
|
||||
/**
|
||||
* The implementation class constructor
|
||||
*/
|
||||
implementationType: Constructor<T>;
|
||||
|
||||
|
||||
/**
|
||||
* The service lifetime
|
||||
*/
|
||||
lifetime: ServiceLifetime;
|
||||
|
||||
|
||||
/**
|
||||
* Optional factory function to create the service instance
|
||||
*/
|
||||
@@ -58,16 +58,16 @@ export type ServiceDescriptor<T = unknown> = {
|
||||
|
||||
/**
|
||||
* Creates a typed service identifier
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
* @returns A unique identifier for the service type
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* interface IUserService {
|
||||
* getUserById(id: string): Promise<User>;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* const userServiceIdentifier = createServiceIdentifier<IUserService>();
|
||||
* ```
|
||||
*/
|
||||
@@ -81,67 +81,82 @@ export function createServiceIdentifier<T>(): ServiceIdentifier<T> {
|
||||
export interface IServiceCollection {
|
||||
/**
|
||||
* Registers a singleton service with the collection
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
* @param serviceType - The service identifier
|
||||
* @param implementationType - The implementation class
|
||||
* @returns The service collection for method chaining
|
||||
*/
|
||||
addSingleton<T>(serviceType: ServiceIdentifier<T>, implementationType: Constructor<T>): IServiceCollection;
|
||||
|
||||
addSingleton<T>(
|
||||
serviceType: ServiceIdentifier<T>,
|
||||
implementationType: Constructor<T>,
|
||||
): IServiceCollection;
|
||||
|
||||
/**
|
||||
* Registers a singleton service with a factory function
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
* @param serviceType - The service identifier
|
||||
* @param factory - A factory function that creates the service instance
|
||||
* @returns The service collection for method chaining
|
||||
*/
|
||||
addSingleton<T>(serviceType: ServiceIdentifier<T>, factory: ServiceFactory<T>): IServiceCollection;
|
||||
|
||||
addSingleton<T>(
|
||||
serviceType: ServiceIdentifier<T>,
|
||||
factory: ServiceFactory<T>,
|
||||
): IServiceCollection;
|
||||
|
||||
/**
|
||||
* Registers a scoped service with the collection
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
* @param serviceType - The service identifier
|
||||
* @param implementationType - The implementation class
|
||||
* @returns The service collection for method chaining
|
||||
*/
|
||||
addScoped<T>(serviceType: ServiceIdentifier<T>, implementationType: Constructor<T>): IServiceCollection;
|
||||
|
||||
addScoped<T>(
|
||||
serviceType: ServiceIdentifier<T>,
|
||||
implementationType: Constructor<T>,
|
||||
): IServiceCollection;
|
||||
|
||||
/**
|
||||
* Registers a scoped service with a factory function
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
* @param serviceType - The service identifier
|
||||
* @param factory - A factory function that creates the service instance
|
||||
* @returns The service collection for method chaining
|
||||
*/
|
||||
addScoped<T>(serviceType: ServiceIdentifier<T>, factory: ServiceFactory<T>): IServiceCollection;
|
||||
|
||||
|
||||
/**
|
||||
* Registers a transient service with the collection
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
* @param serviceType - The service identifier
|
||||
* @param implementationType - The implementation class
|
||||
* @returns The service collection for method chaining
|
||||
*/
|
||||
addTransient<T>(serviceType: ServiceIdentifier<T>, implementationType: Constructor<T>): IServiceCollection;
|
||||
|
||||
addTransient<T>(
|
||||
serviceType: ServiceIdentifier<T>,
|
||||
implementationType: Constructor<T>,
|
||||
): IServiceCollection;
|
||||
|
||||
/**
|
||||
* Registers a transient service with a factory function
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service
|
||||
* @param serviceType - The service identifier
|
||||
* @param factory - A factory function that creates the service instance
|
||||
* @returns The service collection for method chaining
|
||||
*/
|
||||
addTransient<T>(serviceType: ServiceIdentifier<T>, factory: ServiceFactory<T>): IServiceCollection;
|
||||
|
||||
addTransient<T>(
|
||||
serviceType: ServiceIdentifier<T>,
|
||||
factory: ServiceFactory<T>,
|
||||
): IServiceCollection;
|
||||
|
||||
/**
|
||||
* Builds a service provider from the registered services
|
||||
*
|
||||
*
|
||||
* @returns A new service provider instance
|
||||
*/
|
||||
build(): IServiceProvider;
|
||||
@@ -153,20 +168,20 @@ export interface IServiceCollection {
|
||||
export interface IServiceProvider {
|
||||
/**
|
||||
* Gets a service instance by its service identifier
|
||||
*
|
||||
*
|
||||
* @template T - The type of the service to resolve
|
||||
* @param serviceType - The service identifier
|
||||
* @returns The resolved service instance
|
||||
*/
|
||||
getService<T>(serviceType: ServiceIdentifier<T>): T;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new scope for scoped services
|
||||
*
|
||||
*
|
||||
* @returns A new service scope
|
||||
*/
|
||||
createScope(): IServiceScope;
|
||||
|
||||
|
||||
/**
|
||||
* Disposes the service provider and clears any scoped service instances
|
||||
*/
|
||||
@@ -181,7 +196,7 @@ export interface IServiceScope {
|
||||
* The service provider for this scope
|
||||
*/
|
||||
serviceProvider: IServiceProvider;
|
||||
|
||||
|
||||
/**
|
||||
* Disposes the scope and clears any scoped service instances
|
||||
*/
|
||||
|
||||
@@ -5,103 +5,102 @@ describe('ServiceCollection', () => {
|
||||
it('should add a singleton service', () => {
|
||||
class TestService {}
|
||||
const serviceIdentifier = createServiceIdentifier();
|
||||
|
||||
|
||||
const collection = new ServiceCollection();
|
||||
collection.addSingleton(serviceIdentifier, TestService);
|
||||
|
||||
|
||||
const provider = collection.build();
|
||||
const serviceInstance1 = provider.getService(serviceIdentifier);
|
||||
const serviceInstance2 = provider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
expect(serviceInstance1).toBe(serviceInstance2);
|
||||
});
|
||||
|
||||
it('should add a scoped service', () => {
|
||||
class TestService {}
|
||||
const serviceIdentifier = createServiceIdentifier();
|
||||
|
||||
|
||||
const collection = new ServiceCollection();
|
||||
collection.addScoped(serviceIdentifier, TestService);
|
||||
|
||||
|
||||
const provider = collection.build();
|
||||
const scope1 = provider.createScope();
|
||||
const scope2 = provider.createScope();
|
||||
|
||||
|
||||
const serviceInstance1 = scope1.serviceProvider.getService(serviceIdentifier);
|
||||
const serviceInstance2 = scope2.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
expect(serviceInstance1).not.toBe(serviceInstance2);
|
||||
});
|
||||
|
||||
it('should add a transient service', () => {
|
||||
class TestService {}
|
||||
const serviceIdentifier = createServiceIdentifier();
|
||||
|
||||
|
||||
const collection = new ServiceCollection();
|
||||
collection.addTransient(serviceIdentifier, TestService);
|
||||
|
||||
|
||||
const provider = collection.build();
|
||||
|
||||
|
||||
const serviceInstance1 = provider.getService(serviceIdentifier);
|
||||
const serviceInstance2 = provider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
expect(serviceInstance1).not.toBe(serviceInstance2);
|
||||
});
|
||||
|
||||
it('should add a single service with a factory', () => {
|
||||
class TestService {}
|
||||
const serviceIdentifier = createServiceIdentifier();
|
||||
|
||||
|
||||
const collection = new ServiceCollection();
|
||||
collection.addSingleton(serviceIdentifier, () => new TestService());
|
||||
|
||||
|
||||
const provider = collection.build();
|
||||
const serviceInstance1 = provider.getService(serviceIdentifier);
|
||||
const serviceInstance2 = provider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
expect(serviceInstance1).toBe(serviceInstance2);
|
||||
});
|
||||
|
||||
it('should add a scoped service with a factory', () => {
|
||||
class TestService {}
|
||||
const serviceIdentifier = createServiceIdentifier();
|
||||
|
||||
|
||||
const collection = new ServiceCollection();
|
||||
collection.addScoped(serviceIdentifier, () => new TestService());
|
||||
|
||||
|
||||
const provider = collection.build();
|
||||
const scope1 = provider.createScope();
|
||||
const scope2 = provider.createScope();
|
||||
|
||||
|
||||
const serviceInstance1 = scope1.serviceProvider.getService(serviceIdentifier);
|
||||
const serviceInstance2 = scope2.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
expect(serviceInstance1).not.toBe(serviceInstance2);
|
||||
});
|
||||
|
||||
|
||||
it('should add a transient service with a factory', () => {
|
||||
class TestService {}
|
||||
const serviceIdentifier = createServiceIdentifier();
|
||||
|
||||
|
||||
const collection = new ServiceCollection();
|
||||
collection.addTransient(serviceIdentifier, () => new TestService());
|
||||
|
||||
|
||||
const provider = collection.build();
|
||||
|
||||
|
||||
const serviceInstance1 = provider.getService(serviceIdentifier);
|
||||
const serviceInstance2 = provider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
expect(serviceInstance1).not.toBe(serviceInstance2);
|
||||
});
|
||||
|
||||
it('should add a service with a factory and dependencies', () => {
|
||||
type IDependencyService = object
|
||||
type IDependencyService = object;
|
||||
class DependencyService implements IDependencyService {}
|
||||
|
||||
type ITestService = {
|
||||
dependency: IDependencyService;
|
||||
}
|
||||
};
|
||||
class TestService implements ITestService {
|
||||
constructor(public dependency: DependencyService) {}
|
||||
}
|
||||
@@ -111,12 +110,15 @@ describe('ServiceCollection', () => {
|
||||
|
||||
const collection = new ServiceCollection();
|
||||
collection.addSingleton(dependencyServiceIdentifier, DependencyService);
|
||||
collection.addSingleton(testServiceIdentifier, (provider) => new TestService(provider.getService(dependencyServiceIdentifier)));
|
||||
|
||||
collection.addSingleton(
|
||||
testServiceIdentifier,
|
||||
provider => new TestService(provider.getService(dependencyServiceIdentifier)),
|
||||
);
|
||||
|
||||
const provider = collection.build();
|
||||
const serviceInstance1 = provider.getService(testServiceIdentifier);
|
||||
const serviceInstance2 = provider.getService(testServiceIdentifier);
|
||||
|
||||
|
||||
expect(serviceInstance1).toBe(serviceInstance2);
|
||||
expect(serviceInstance1.dependency).toBe(serviceInstance2.dependency);
|
||||
});
|
||||
|
||||
@@ -247,7 +247,7 @@ describe('ServiceProvider', () => {
|
||||
);
|
||||
|
||||
const userService = serviceProvider.getService(userServiceIdentifier);
|
||||
|
||||
|
||||
const user = userService.getUser();
|
||||
|
||||
expect(user).toBe('John Doe');
|
||||
@@ -255,9 +255,9 @@ describe('ServiceProvider', () => {
|
||||
|
||||
it('should throw an error when service has invalid lifetime', () => {
|
||||
type IService = object;
|
||||
|
||||
|
||||
const serviceIdentifier = createServiceIdentifier<IService>();
|
||||
|
||||
|
||||
const serviceProvider = new ServiceProvider(
|
||||
new Map([
|
||||
[
|
||||
@@ -341,9 +341,9 @@ describe('ServiceProvider', () => {
|
||||
);
|
||||
|
||||
const initialService = serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
serviceProvider.dispose();
|
||||
|
||||
|
||||
const newService = serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
expect(initialService).not.toBe(newService);
|
||||
@@ -380,9 +380,9 @@ describe('ServiceProvider', () => {
|
||||
const scope = serviceProvider.createScope();
|
||||
|
||||
const initialService = scope.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
scope.dispose();
|
||||
|
||||
|
||||
const newService = scope.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
expect(initialService).not.toBe(newService);
|
||||
@@ -419,15 +419,15 @@ describe('ServiceProvider', () => {
|
||||
const scope = serviceProvider.createScope();
|
||||
|
||||
const initialService = scope.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
serviceProvider.dispose();
|
||||
|
||||
|
||||
const newService = scope.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
expect(initialService).toBe(newService);
|
||||
});
|
||||
|
||||
it("should not clear the scoped instances on dispose from another scope when one scope is disposed", () => {
|
||||
it('should not clear the scoped instances on dispose from another scope when one scope is disposed', () => {
|
||||
type IService = {
|
||||
id: string;
|
||||
};
|
||||
@@ -460,9 +460,9 @@ describe('ServiceProvider', () => {
|
||||
|
||||
const initialService1 = scope1.serviceProvider.getService(serviceIdentifier);
|
||||
const initialService2 = scope2.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
|
||||
scope1.dispose();
|
||||
|
||||
|
||||
const newService1 = scope1.serviceProvider.getService(serviceIdentifier);
|
||||
const newService2 = scope2.serviceProvider.getService(serviceIdentifier);
|
||||
|
||||
@@ -501,7 +501,7 @@ describe('ServiceProvider', () => {
|
||||
],
|
||||
]),
|
||||
);
|
||||
|
||||
|
||||
expect(() => {
|
||||
serviceProvider.getService(userServiceIdentifier);
|
||||
}).toThrowError();
|
||||
|
||||
Reference in New Issue
Block a user