-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
126 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Token } from './Token'; | ||
|
||
export type Provider<T = any> = ValueProvider<T>; | ||
|
||
export type ValueProvider<T = any> = { | ||
provide: Token; | ||
useValue: T; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { Type } from './Type'; | ||
|
||
export type Token<T = any> = string | symbol | Type<T>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Token } from '@lery/common/Token'; | ||
|
||
export class InstanceContainer { | ||
private readonly instanceMap: Map<Token, any> = new Map(); | ||
|
||
register<T>(token: Token<T>, instance: T): void { | ||
this.instanceMap.set(token, instance); | ||
} | ||
|
||
get<T>(token: Token<T>): T { | ||
if (!this.instanceMap.has(token)) { | ||
throw new Error(`No instance found for token ${token.toString()}`); | ||
} | ||
|
||
return this.instanceMap.get(token); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,14 @@ | ||
import { Token } from '@lery/common/Token'; | ||
|
||
export const PARAMETER_INJECT_METADATA = 'PARAMETER_INJECT_METADATA' as const; | ||
export const PROPERTY_INJECT_METADATA = 'PROPERTY_INJECT_METADATA' as const; | ||
|
||
export type ParameterInjectMetadata = { | ||
token: string; | ||
token: Token; | ||
index: number; | ||
}; | ||
|
||
export type PropertyInjectMetadata = { | ||
token: string; | ||
token: Token; | ||
propertyKey: string | symbol; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { Provider } from '@lery/common/Provider'; | ||
import { Token } from '@lery/common/Token'; | ||
import { Type } from '@lery/common/Type'; | ||
import { | ||
PARAMETER_INJECT_METADATA, | ||
PROPERTY_INJECT_METADATA, | ||
ParameterInjectMetadata, | ||
PropertyInjectMetadata, | ||
} from '@lery/core/metadata/InjectMetadata'; | ||
import { InstanceContainer } from '../container/InstanceContainer'; | ||
|
||
export class Resolver { | ||
private readonly instanceContainer: InstanceContainer; | ||
|
||
constructor() { | ||
this.instanceContainer = new InstanceContainer(); | ||
} | ||
|
||
registerProviders(providers: Provider[]): void { | ||
providers.forEach((provider) => { | ||
this.instanceContainer.register(provider.provide, provider.useValue); | ||
}); | ||
} | ||
|
||
resolve<T>(ctor: Type<T>): T { | ||
const parameters = this.resolveConstructorParameters(ctor); | ||
const instance = new ctor(...parameters); | ||
this.resolveProperty(ctor, instance); | ||
|
||
return instance; | ||
} | ||
|
||
resolveConstructorParameters<T>(ctor: Type<T>): any[] { | ||
const metadata: ParameterInjectMetadata[] = | ||
Reflect.getMetadata(PARAMETER_INJECT_METADATA, ctor) ?? []; | ||
|
||
const result: any[] = []; | ||
metadata.map((m) => { | ||
result[m.index] = this.instanceContainer.get(m.token); | ||
}); | ||
|
||
return result; | ||
} | ||
|
||
resolveProperty<T>(ctor: Type<T>, instance: T): void { | ||
const metadata: PropertyInjectMetadata[] = | ||
Reflect.getMetadata(PROPERTY_INJECT_METADATA, ctor) ?? []; | ||
|
||
metadata.forEach((m) => { | ||
(instance as any)[m.propertyKey] = this.instanceContainer.get(m.token); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
export const CalculatorToken = Symbol('Calculator'); | ||
|
||
export interface ICalculator { | ||
add: (a: number, b: number) => number; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
export const HelloWorldToken = Symbol('HelloWorld'); | ||
|
||
export interface IHelloWorld { | ||
sayHello: () => void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,55 @@ | ||
import 'reflect-metadata'; | ||
import { Resolver } from '@lery/resolver/Resolver'; | ||
|
||
import { Resolver } from '@lery/core/resolver/Resolver'; | ||
import { Calculator } from '@lery/instances/calculator/Calculator'; | ||
import { Logger } from '@lery/instances/logger/Logger'; | ||
import { HelloWorld } from '@lery/instances/helloWorld/HelloWorld'; | ||
import { FileManager } from '@lery/instances/fileManager/FileManager'; | ||
import { Inject } from '@lery/decorators/Inject'; | ||
import { | ||
CalculatorToken, | ||
ICalculator, | ||
} from '@lery/instances/calculator/ICalculator'; | ||
import { ILogger, LoggerToken } from '@lery/instances/logger/ILogger'; | ||
import { | ||
InjectCalculator, | ||
InjectFileManager, | ||
InjectHelloWorld, | ||
InjectLogger, | ||
} from './decorators/Inject'; | ||
import { ICalculator } from './instances/calculator/ICalculator'; | ||
import { ILogger } from './instances/logger/ILogger'; | ||
import { IHelloWorld } from './instances/helloWorld/IHelloWorld'; | ||
import { IFileManager } from './instances/fileManager/IFileManager'; | ||
HelloWorldToken, | ||
IHelloWorld, | ||
} from '@lery/instances/helloWorld/IHelloWorld'; | ||
import { | ||
FileManagerToken, | ||
IFileManager, | ||
} from '@lery/instances/fileManager/IFileManager'; | ||
|
||
class Hello { | ||
@InjectCalculator() | ||
@Inject(CalculatorToken) | ||
calculator!: ICalculator; | ||
|
||
@InjectLogger() | ||
@Inject(LoggerToken) | ||
logger!: ILogger; | ||
|
||
constructor( | ||
@InjectHelloWorld() | ||
@Inject(HelloWorldToken) | ||
readonly helloWorld: IHelloWorld, | ||
@InjectFileManager() | ||
@Inject(FileManagerToken) | ||
readonly fileManager: IFileManager | ||
) {} | ||
} | ||
|
||
function main() { | ||
const resolver = new Resolver({ | ||
calculator: new Calculator(), | ||
logger: new Logger(), | ||
helloWorld: new HelloWorld(), | ||
fileManager: new FileManager(), | ||
}); | ||
const resolver = new Resolver(); | ||
resolver.registerProviders([ | ||
{ provide: CalculatorToken, useValue: new Calculator() }, | ||
{ provide: LoggerToken, useValue: new Logger() }, | ||
{ provide: HelloWorldToken, useValue: new HelloWorld() }, | ||
{ provide: FileManagerToken, useValue: new FileManager() }, | ||
]); | ||
|
||
const hello = resolver.resolve(Hello); | ||
console.log(hello); | ||
|
||
console.log(hello.calculator.add(1, 2)); // 3 | ||
hello.logger.log('Hello from logger'); // Hello from logger | ||
hello.helloWorld.sayHello(); // Hello, World! | ||
hello.fileManager.write('some.txt', 'Hello!'); // Writing file to some.txt with content: Hello! | ||
} | ||
|
||
main(); |
This file was deleted.
Oops, something went wrong.