Refactor DI container for better structure and clarity
- Moved `TSinjex` class to `classes` directory for better organization. - Updated imports across the codebase to reflect the new location of `TSinjex`. - Introduced `Identifier` type to standardize dependency identifiers. - Enhanced JSDoc comments for improved clarity and consistency. - Adjusted error messages for `DependencyResolutionError` to provide clearer information. - Updated and expanded decorator and function types to use `Identifier` type.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { test_IDIContainer } from './IDIContainer.spec';
|
||||
import { TSinjex } from '../TSinjex';
|
||||
import { TSinjex } from '../classes/TSinjex';
|
||||
|
||||
test_IDIContainer(TSinjex);
|
||||
|
@@ -1,104 +1,127 @@
|
||||
import { ImplementsStatic } from './helper/ImplementsStatic';
|
||||
import { DependencyResolutionError } from './interfaces/Exceptions';
|
||||
import { IDependency } from './interfaces/IDependency';
|
||||
import { ITSinjex, ITSinjex_ } from './interfaces/ITSinjex';
|
||||
|
||||
/**
|
||||
* **TSInjex**: Dependency Injection Container
|
||||
*/
|
||||
@ImplementsStatic<ITSinjex_>()
|
||||
export class TSinjex implements ITSinjex {
|
||||
private static _instance: TSinjex;
|
||||
private readonly _dependencies = new Map<string, IDependency>();
|
||||
|
||||
/**
|
||||
* Private constructor to prevent direct instantiation.
|
||||
*/
|
||||
private constructor() {}
|
||||
|
||||
//#region IDIContainer_
|
||||
|
||||
/**
|
||||
* Retrieves the singleton instance of DependencyRegistry.
|
||||
* @returns The singleton instance.
|
||||
*/
|
||||
public static getInstance(): ITSinjex {
|
||||
if (this._instance == null) {
|
||||
this._instance = new TSinjex();
|
||||
}
|
||||
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @see {@link ITSinjex.register}
|
||||
*/
|
||||
public static register<T>(
|
||||
identifier: string,
|
||||
dependency: T,
|
||||
deprecated = false,
|
||||
): void {
|
||||
(TSinjex.getInstance() as TSinjex)._dependencies.set(identifier, {
|
||||
dependency: dependency,
|
||||
deprecated: deprecated,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @see {@link ITSinjex.resolve}
|
||||
*/
|
||||
public static resolve<T>(
|
||||
identifier: string,
|
||||
necessary = true,
|
||||
): T | undefined {
|
||||
return (TSinjex.getInstance() as TSinjex).resolve<T>(
|
||||
identifier,
|
||||
necessary,
|
||||
);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region IDIContainer
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public register<T>(
|
||||
identifier: string,
|
||||
dependency: T,
|
||||
deprecated = false,
|
||||
): void {
|
||||
this._dependencies.set(identifier, {
|
||||
dependency: dependency,
|
||||
deprecated: deprecated,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public resolve<T>(identifier: string, necessary = true): T | undefined {
|
||||
const dependency = this._dependencies.get(identifier);
|
||||
|
||||
if (necessary && !dependency) {
|
||||
throw new DependencyResolutionError(identifier);
|
||||
} else if (!dependency) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (dependency.deprecated) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Dependency ${identifier} is deprecated`);
|
||||
|
||||
// Remove the deprecation warning; it should only be logged once.
|
||||
dependency.deprecated = false;
|
||||
}
|
||||
|
||||
return dependency.dependency as T;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
import { Identifier } from 'src/types/Identifier';
|
||||
import type { Inject } from '../decorators/Inject';
|
||||
import type { Register } from '../decorators/Register';
|
||||
import type { RegisterInstance } from '../decorators/RegisterInstance';
|
||||
import type { register } from '../functions/register';
|
||||
import type { resolve } from '../functions/resolve';
|
||||
import { ImplementsStatic } from '../helper/ImplementsStatic';
|
||||
import { DependencyResolutionError } from '../interfaces/Exceptions';
|
||||
import { IDependency } from '../interfaces/IDependency';
|
||||
import { ITSinjex, ITSinjex_ } from '../interfaces/ITSinjex';
|
||||
|
||||
/**
|
||||
* # TSinjex
|
||||
* The main class for the Dependency Injection Container **TSinjex**.
|
||||
* ### Decorators
|
||||
* @see {@link Register} for registering a class in the DI container.
|
||||
* @see {@link RegisterInstance} for registering an instance in the DI container.
|
||||
* @see {@link Inject} for injecting a dependency into a property.
|
||||
* ---
|
||||
* ### Functions
|
||||
* @see {@link register} for registering a dependency (class or instance) as a function.
|
||||
* @see {@link resolve} for resolving a dependency as a function.
|
||||
*/
|
||||
@ImplementsStatic<ITSinjex_>()
|
||||
export class TSinjex implements ITSinjex {
|
||||
/**
|
||||
* The singleton instance of the TSinjex class.
|
||||
*/
|
||||
private static _instance: TSinjex;
|
||||
|
||||
/**
|
||||
* The dependencies map.
|
||||
*/
|
||||
private readonly _dependencies = new Map<Identifier, IDependency>();
|
||||
|
||||
/**
|
||||
* Private constructor to prevent direct instantiation.
|
||||
*/
|
||||
private constructor() {}
|
||||
|
||||
//#region ITSinjex_ (Static)
|
||||
|
||||
/**
|
||||
* Get the **singleton** TSInjex instance.
|
||||
* @returns The singleton instance.
|
||||
*/
|
||||
public static getInstance(): ITSinjex {
|
||||
if (this._instance == null) {
|
||||
this._instance = new TSinjex();
|
||||
}
|
||||
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static implementation of {@link ITSinjex.register}.
|
||||
* @see {@link ITSinjex.register}
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static register<T>(
|
||||
identifier: Identifier,
|
||||
dependency: T,
|
||||
deprecated = false,
|
||||
): void {
|
||||
(TSinjex.getInstance() as TSinjex)._dependencies.set(identifier, {
|
||||
dependency: dependency,
|
||||
deprecated: deprecated,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Static implementation of {@link ITSinjex.resolve}.
|
||||
* @see {@link ITSinjex.resolve}
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static resolve<T>(
|
||||
identifier: Identifier,
|
||||
necessary = true,
|
||||
): T | undefined {
|
||||
return (TSinjex.getInstance() as TSinjex).resolve<T>(
|
||||
identifier,
|
||||
necessary,
|
||||
);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ITSinjex (Instance)
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public register<T>(
|
||||
identifier: Identifier,
|
||||
dependency: T,
|
||||
deprecated = false,
|
||||
): void {
|
||||
this._dependencies.set(identifier, {
|
||||
dependency: dependency,
|
||||
deprecated: deprecated,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public resolve<T>(identifier: Identifier, necessary = true): T | undefined {
|
||||
const dependency = this._dependencies.get(identifier);
|
||||
|
||||
if (necessary && !dependency) {
|
||||
throw new DependencyResolutionError(identifier);
|
||||
} else if (!dependency) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (dependency.deprecated) {
|
||||
console.warn(`Dependency ${identifier} is deprecated`);
|
||||
|
||||
// Remove the deprecation warning; it should only be logged once.
|
||||
dependency.deprecated = false;
|
||||
}
|
||||
|
||||
return dependency.dependency as T;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
@@ -1,18 +1,19 @@
|
||||
import { TSinjex } from '../TSinjex';
|
||||
import { Identifier } from 'src/types/Identifier';
|
||||
import { TSinjex } from '../classes/TSinjex';
|
||||
import { InitDelegate } from '../types/InitDelegate';
|
||||
|
||||
/**
|
||||
* A decorator to inject a dependency from a DI (Dependency Injection) container.
|
||||
* The dependency is lazily evaluated when the property is accessed for the first time.
|
||||
* This can help avoid issues like circular dependencies and not-found dependencies.
|
||||
* @template ClassType The type of the property to be injected.
|
||||
* @param identifier The identifier used to resolve the dependency from the DI container.
|
||||
* A decorator to inject a dependency from a DI (Dependency Injection) container into a class property.
|
||||
* @template T The type of the dependency to be injected.
|
||||
* @template U The type of the property to be injected.
|
||||
* @param identifier The identifier used to resolve the class in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @param init An optional initializer function to transform the dependency before injection.
|
||||
* @param necessary Indicates if the dependency is necessary.
|
||||
* - If `true`, an error will be thrown if the dependency cannot be resolved.
|
||||
* - If `false`, `undefined` will be returned if the dependency cannot be resolved.
|
||||
* @returns A decorator function to be applied on the class property.
|
||||
* @see {@link TSinjex}
|
||||
* @see {@link InitDelegate} for more information on initializer functions.
|
||||
* @param necessary If true, throws an error if the dependency is not found.
|
||||
* @returns The resolved dependency or undefined if the dependency is not necessary
|
||||
* and not found, or throws an error if the dependency is necessary and not found.
|
||||
* @throws A {@link DependencyResolutionError} if the dependency is not found and necessary.
|
||||
* @example
|
||||
* ```ts
|
||||
* class MyClass {
|
||||
@@ -29,7 +30,7 @@ import { InitDelegate } from '../types/InitDelegate';
|
||||
* ```
|
||||
*/
|
||||
export function Inject<T, U>(
|
||||
identifier: string,
|
||||
identifier: Identifier,
|
||||
init?: InitDelegate<T, U>,
|
||||
necessary = true,
|
||||
) {
|
||||
|
@@ -1,12 +1,14 @@
|
||||
import { TSinjex } from '../TSinjex';
|
||||
import { Identifier } from 'src/types/Identifier';
|
||||
import { TSinjex } from '../classes/TSinjex';
|
||||
|
||||
/**
|
||||
* A decorator to register a class in the DI (Dependency Injection) container.
|
||||
* A decorator to register a class in the **TSinjex** DI (Dependency Injection) container.
|
||||
* @template TargetType The type of the class to be registered.
|
||||
* @param identifier The identifier used to register the class in the DI container.
|
||||
* @param deprecated If true, the dependency is deprecated => a warning
|
||||
* is logged when the dependency is resolved.
|
||||
* @returns A function that is applied as a decorator to the class.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @param deprecated If true, the dependency is deprecated and a warning
|
||||
* is logged only once upon the first resolution of the dependency.
|
||||
* @returns The decorator function to be applied on the class.
|
||||
* @example
|
||||
* ```ts
|
||||
* \@Register('MyClassIdentifier')
|
||||
@@ -17,7 +19,7 @@ import { TSinjex } from '../TSinjex';
|
||||
*/
|
||||
export function Register<
|
||||
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
||||
>(identifier: string, deprecated?: boolean) {
|
||||
>(identifier: Identifier, deprecated?: boolean) {
|
||||
return function (constructor: TargetType, ...args: unknown[]): void {
|
||||
// Get the instance of the DI container
|
||||
const diContainer = TSinjex.getInstance();
|
||||
|
@@ -1,17 +1,19 @@
|
||||
import { TSinjex } from '../TSinjex';
|
||||
import { Identifier } from 'src/types/Identifier';
|
||||
import { TSinjex } from '../classes/TSinjex';
|
||||
import { InitDelegate } from '../types/InitDelegate';
|
||||
|
||||
/**
|
||||
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
||||
* The instance is created only when it is first needed (Lazy Initialization).
|
||||
* @template TargetType The type of the class whose instance is to be registered.
|
||||
* @param identifier The identifier used to register the instance in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @param init An optional initializer function which get the constructor of the class
|
||||
* as input and returns an instance of the class.
|
||||
* @returns A function that is applied as a decorator to the class.
|
||||
* @see {@link InitDelegate} for more information on initializer functions.
|
||||
* @returns The decorator function to be applied on the class.
|
||||
* @example
|
||||
* ```ts
|
||||
* \@RegisterInstance('MyClassInstanceIdentifier', arg1, arg2)
|
||||
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor())
|
||||
* class MyClass {
|
||||
* // ...
|
||||
* }
|
||||
@@ -20,7 +22,7 @@ import { InitDelegate } from '../types/InitDelegate';
|
||||
export function RegisterInstance<
|
||||
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
||||
>(
|
||||
identifier: string,
|
||||
identifier: Identifier,
|
||||
init?: InitDelegate<
|
||||
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
||||
InstanceType<TargetType>
|
||||
|
@@ -1,33 +1,37 @@
|
||||
import { TSinjex } from '../TSinjex';
|
||||
import { Identifier } from 'src/types/Identifier';
|
||||
import { TSinjex } from '../classes/TSinjex';
|
||||
|
||||
/**
|
||||
* Register a dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param identifier The identifier used to register the class in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers..
|
||||
* @param dependency The dependency to register.
|
||||
*/
|
||||
export function register<T>(identifier: string, dependency: T): void;
|
||||
export function register<T>(identifier: Identifier, dependency: T): void;
|
||||
|
||||
/**
|
||||
* Register a dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param identifier The identifier used to register the class in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @param dependency The dependency to register.
|
||||
* @param deprecated A warning is logged when the dependency is resolved.
|
||||
*/
|
||||
export function register<T>(
|
||||
identifier: string,
|
||||
identifier: Identifier,
|
||||
dependency: T,
|
||||
deprecated?: true,
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Register a dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param identifier The identifier used to register the class in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @param dependency The dependency to register.
|
||||
* @param deprecated If true, the dependency is deprecated => a warning
|
||||
* is logged when the dependency is resolved.
|
||||
*/
|
||||
export function register<T>(
|
||||
identifier: string,
|
||||
identifier: Identifier,
|
||||
dependency: T,
|
||||
deprecated?: boolean,
|
||||
): void {
|
||||
|
@@ -1,32 +1,39 @@
|
||||
import { Identifier } from 'src/types/Identifier';
|
||||
import { TSinjex } from '../classes/TSinjex';
|
||||
import { DependencyResolutionError } from '../interfaces/Exceptions';
|
||||
import { TSinjex } from '../TSinjex';
|
||||
|
||||
/**
|
||||
* Resolve a dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param identifier The identifier used to register the class in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @returns The resolved dependency.
|
||||
* @throws A {@link DependencyResolutionError} if the dependency is not found.
|
||||
*/
|
||||
export function resolve<T>(identifier: string): T;
|
||||
export function resolve<T>(identifier: Identifier): T;
|
||||
|
||||
/**
|
||||
* Resolve a dependency
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param identifier The identifier used to register the class in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @param necessary The dependency is **not** necessary.
|
||||
* @returns The resolved dependency or undefined if the dependency is not found.
|
||||
*/
|
||||
export function resolve<T>(identifier: string, necessary: false): T | undefined;
|
||||
export function resolve<T>(
|
||||
identifier: Identifier,
|
||||
necessary: false,
|
||||
): T | undefined;
|
||||
|
||||
/**
|
||||
* Resolve a dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param identifier The identifier used to register the class in the DI container.
|
||||
* @see {@link Identifier} for more information on identifiers.
|
||||
* @param necessary If true, throws an error if the dependency is not found.
|
||||
* @returns The resolved dependency or undefined if the dependency is not necessary
|
||||
* and not found, or throws an error if the dependency is necessary and not found.
|
||||
* @throws A {@link DependencyResolutionError} if the dependency is not found and necessary.
|
||||
*/
|
||||
export function resolve<T>(
|
||||
identifier: string,
|
||||
identifier: Identifier,
|
||||
necessary?: boolean,
|
||||
): T | undefined {
|
||||
return TSinjex.getInstance().resolve<T>(identifier, necessary);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// Main
|
||||
export * from './TSinjex';
|
||||
export * from './classes/TSinjex';
|
||||
|
||||
// Decorators
|
||||
export * from './decorators/Inject';
|
||||
|
@@ -10,7 +10,7 @@ export class TSinjexError extends Error {
|
||||
*/
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'TSInjex';
|
||||
this.name = 'TSinjex';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export class DependencyResolutionError extends TSinjexError {
|
||||
* @param identifier **The identifier of the dependency**
|
||||
*/
|
||||
constructor(identifier: string) {
|
||||
super(`Dependency ${identifier} not found.`);
|
||||
this.name = 'TSInjexResolutionError';
|
||||
super(`Dependency ${identifier} could not be resolved.`);
|
||||
this.name = 'TSinjexResolutionError';
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,19 @@
|
||||
import { Identifier } from 'src/types/Identifier';
|
||||
import { DependencyResolutionError } from './Exceptions';
|
||||
|
||||
/**
|
||||
* Static TSInjex Interface
|
||||
*/
|
||||
export interface ITSinjex_ extends ITSinjexRegister, ITSinjexResolve {
|
||||
/**
|
||||
* Get the **singleton** TSInjex instance.
|
||||
* @returns The singleton instance.
|
||||
*/
|
||||
getInstance(): ITSinjex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register method for static and instance Dependency Injection Container.
|
||||
* `Register` method for static and instance Dependency Injection Container.
|
||||
*/
|
||||
export interface ITSinjexRegister {
|
||||
/**
|
||||
@@ -19,25 +23,33 @@ export interface ITSinjexRegister {
|
||||
* @param deprecated If true, the dependency is deprecated => a warning
|
||||
* is logged when the dependency is resolved.
|
||||
*/
|
||||
register<T>(identifier: string, dependency: T, deprecated?: boolean): void;
|
||||
register<T>(
|
||||
identifier: Identifier,
|
||||
dependency: T,
|
||||
deprecated?: boolean,
|
||||
): void;
|
||||
/**
|
||||
* Register a deprecated dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param dependency The dependency to register.
|
||||
* @param deprecated A warning is logged when the dependency is resolved.
|
||||
*/
|
||||
register<T>(identifier: string, dependency: T, deprecated?: true): void;
|
||||
register<T>(identifier: Identifier, dependency: T, deprecated?: true): void;
|
||||
/**
|
||||
* Register a dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param dependency The dependency to register.
|
||||
* @param deprecated No warning is logged when the dependency is resolved.
|
||||
*/
|
||||
register<T>(identifier: string, dependency: T, deprecated?: false): void;
|
||||
register<T>(
|
||||
identifier: Identifier,
|
||||
dependency: T,
|
||||
deprecated?: false,
|
||||
): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve method for static and instance Dependency Injection Container.
|
||||
* `Resolve` method for static and instance Dependency Injection Container.
|
||||
*/
|
||||
export interface ITSinjexResolve {
|
||||
/**
|
||||
@@ -45,26 +57,27 @@ export interface ITSinjexResolve {
|
||||
* @param identifier The identifier of the dependency
|
||||
* @param necessary If true, throws an error if the dependency is not found
|
||||
* @returns The resolved dependency or undefined if the dependency is not found
|
||||
* @throws A {@link DependencyResolutionError} if the dependency is not found and necessary.
|
||||
*/
|
||||
resolve<T>(identifier: string, necessary?: boolean): T | undefined;
|
||||
resolve<T>(identifier: Identifier, necessary?: boolean): T | undefined;
|
||||
/**
|
||||
* Resolve a necessary dependency.
|
||||
* @param identifier The identifier of the dependency.
|
||||
* @param necessary If true, throws an error if the dependency is not found.
|
||||
* @returns The resolved dependency.
|
||||
* @throws Error if the dependency is not found.
|
||||
* @throws A {@link DependencyResolutionError} if the dependency is not found.
|
||||
*/
|
||||
resolve<T>(identifier: string, necessary?: true): T;
|
||||
resolve<T>(identifier: Identifier, necessary?: true): T;
|
||||
/**
|
||||
* Resolve a non necessary dependency
|
||||
* @param identifier The identifier of the dependency
|
||||
* @param necessary Not necessary, does not throw an error if the dependency is not found.
|
||||
* @returns The resolved dependency or undefined if the dependency is not found
|
||||
*/
|
||||
resolve<T>(identifier: string, necessary?: false): T | undefined;
|
||||
resolve<T>(identifier: Identifier, necessary?: false): T | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* TSInjex Interface
|
||||
* Instance TSinjex Interface
|
||||
*/
|
||||
export interface ITSinjex extends ITSinjexRegister, ITSinjexResolve {}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* Generic constructor type.
|
||||
* This type is used to define a constructor of a class.
|
||||
*/
|
||||
export type GenericConstructor<
|
||||
T extends abstract new (...args: unknown[]) => InstanceType<T>,
|
||||
@@ -7,6 +8,6 @@ export type GenericConstructor<
|
||||
|
||||
/**
|
||||
* Force generic constructor type.
|
||||
* This type is used to force a class to be a constructor.
|
||||
* This type is used to force a class to has a constructor.
|
||||
*/
|
||||
export type ForceConstructor<T> = new (...args: unknown[]) => T;
|
||||
|
11
src/types/Identifier.ts
Normal file
11
src/types/Identifier.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* The dependency identifier.
|
||||
* You can use any string as identifier.
|
||||
* To create order, it is also possible to
|
||||
* provide these with a separator: `GroupA.ClassZ`.
|
||||
* The convection for naming is as follows:
|
||||
* The name should generally correspond to the interface that is relevant.
|
||||
* I.e. a class `ClassA` that implements the interface `IClassA` and is
|
||||
* registered as a dependent class is registered under the interface name `IClassA`.
|
||||
*/
|
||||
export type Identifier = string;
|
Reference in New Issue
Block a user