# HG changeset patch # User cin # Date 2020-07-17 18:27:47 # Node ID 850cc60b6e2aaee96170ff36722812b8820abf08 # Parent 142c5f6dc2b5779d377d3686b409c07126fc8b7c fluent configuration interfaces diff --git a/src/main/ts/di/Annotations.ts b/src/main/ts/di/Annotations.ts --- a/src/main/ts/di/Annotations.ts +++ b/src/main/ts/di/Annotations.ts @@ -1,24 +1,8 @@ -import { primitive } from "../safe"; -import { TypeRegistration, DependencyRegistration, LazyDependencyRegistration, Registration, StrictTypeRegistration } from "./Configuration"; - -export interface InjectOptions { - lazy?: boolean; -} - -type Compatible = T2 extends T1 ? any : never; - -type ExtractService = K extends keyof S ? S[K] : K; +import { TypeRegistration } from "./Configuration"; +import { ExtractDependency } from "./fluent/interfaces"; -type ExtractDependency = D extends { $dependency: infer K } ? - D extends { lazy: true } ? () => ExtractService : ExtractService : - D extends { $type: new (...args: any[]) => infer I } ? I : - WalkDependencies; - -type WalkDependencies = D extends primitive ? D : - { [K in keyof D]: ExtractDependency }; - -export class Builder { - declare

(...args: P) { +export class AnnotaionBuilder { + wire

(...args: P) { return ) => T>(constructor: C) => { }; @@ -28,7 +12,7 @@ export class Builder any }, M extends keyof (T | X)>( target: X, memberName: M, - descriptor: TypedPropertyDescriptor) => any, T[M]>> + descriptor: TypedPropertyDescriptor< T[M] extends ((...args: ExtractDependency) => any) ? any : never > ) => { }; @@ -39,24 +23,3 @@ export class Builder { - optional?: boolean; - default?: T; -} - -export interface LazyDependencyOptions extends DependencyOptions { - lazy: true; -} - -interface Declaration { - define(): Builder; - - dependency(name: K, opts: LazyDependencyOptions): LazyDependencyRegistration; - dependency(name: K, opts?: DependencyOptions): DependencyRegistration; - - $type) => T>(target: C, ...params: P): StrictTypeRegistration; -} - - -export declare function declare(): Declaration; diff --git a/src/main/ts/di/fluent/interfaces.ts b/src/main/ts/di/fluent/interfaces.ts --- a/src/main/ts/di/fluent/interfaces.ts +++ b/src/main/ts/di/fluent/interfaces.ts @@ -1,47 +1,68 @@ import { primitive } from "../../safe"; import { ActivationType } from "../interfaces"; -import { Builder } from "../Annotations"; +import { AnnotaionBuilder } from "../Annotations"; +import { LazyDependencyRegistration, DependencyRegistration } from "../Configuration"; +import { PromiseOrValue } from "../../interfaces"; -type ExtractService = K extends keyof S ? S[K] : K; +export interface DependencyOptions { + optional?: boolean; + default?: T; +} -type ExtractDependency = D extends { $dependency: infer K } ? +export interface LazyDependencyOptions extends DependencyOptions { + lazy: true; +} + +export type ExtractService = K extends keyof S ? S[K] : K; + +export type ExtractDependency = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService : ExtractService : D extends { $type: new (...args: any[]) => infer I } ? I : D extends { $factory: (...args: any[]) => infer R } ? R : WalkDependencies; -type WalkDependencies = D extends primitive ? D : +export type WalkDependencies = D extends primitive ? D : { [K in keyof D]: ExtractDependency }; -type ServiceModule = { - [m in M]: Builder; +export type ServiceModule = { + [m in M]: AnnotaionBuilder; }; -type PromiseOrValue = T | PromiseLike; - -export interface TypeBuilder { +export interface ServiceBuilder { type

) => T>( target: C, ...params: P): ConstructorBuilder; factory

) => T>( target: F, ...params: P): FactoryBuilder; - wire(module: PromiseOrValue>, m: M): ServiceBuilder; - wire(module: PromiseOrValue>): ServiceBuilder; + wired(module: PromiseOrValue>, m: M): RegistrationBuilder; + wired(module: PromiseOrValue>): RegistrationBuilder; } -export interface ServiceBuilder { - override(name: K, builder: S[K] | ((t: TypeBuilder) => any)): this; +export interface RegistrationBuilder { + override(name: K, builder: S[K] | ((t: ServiceBuilder) => any)): this; activate(activation: ActivationType): this; inject(member: T[M] extends (...params: ExtractDependency) => any ? M : never, ...params: P): this; } -export interface ConstructorBuilder any, S extends object> extends ServiceBuilder, S> { +export interface ConstructorBuilder any, S extends object> extends RegistrationBuilder, S> { $type: C; } -export interface FactoryBuilder any, S extends object> extends ServiceBuilder, S> { +export interface FactoryBuilder any, S extends object> extends RegistrationBuilder, S> { $factory: F; } export interface ConfigBuilder { - register(name: K, builder: S[K] | ((t: TypeBuilder) => any)): ConfigBuilder>; + register(name: K, builder: S[K] | ((t: ServiceBuilder) => any)): ConfigBuilder>; } + +interface ServicesDeclaration { + build(this: void): ServiceBuilder; + annotate(this: void): AnnotaionBuilder; + + dependency(this: void, name: K, opts: LazyDependencyOptions): LazyDependencyRegistration; + dependency(this: void, name: K, opts?: DependencyOptions): DependencyRegistration; + + configure(): ConfigBuilder; +} + +export declare function declare(): ServicesDeclaration; diff --git a/src/main/ts/interfaces.ts b/src/main/ts/interfaces.ts --- a/src/main/ts/interfaces.ts +++ b/src/main/ts/interfaces.ts @@ -3,6 +3,8 @@ export interface Constructor { prototype: T; } +export type PromiseOrValue = T | PromiseLike; + export type Factory = (...args: any[]) => T; export type Predicate = (x: T) => boolean; diff --git a/src/test/ts/mock/Bar.ts b/src/test/ts/mock/Bar.ts --- a/src/test/ts/mock/Bar.ts +++ b/src/test/ts/mock/Bar.ts @@ -1,9 +1,9 @@ import { Foo } from "./Foo"; -import { define, dependency } from "./services"; +import { annotate, dependency } from "./services"; -export const service = define(); +export const service = annotate(); -@service.declare({ +@service.wire({ foo: dependency("foo"), nested: { lazy: dependency("foo", { lazy: true }) @@ -11,7 +11,7 @@ export const service = define(); host: dependency("host") }, "") export class Bar { - barName = "bar"; + barName = "Twister"; _v: Foo | undefined; diff --git a/src/test/ts/mock/Box.ts b/src/test/ts/mock/Box.ts --- a/src/test/ts/mock/Box.ts +++ b/src/test/ts/mock/Box.ts @@ -1,16 +1,16 @@ import { Bar } from "./Bar"; -import { define, dependency } from "./services"; +import { annotate, dependency } from "./services"; // export service descriptor // через service передается информация о типе зависимости // даже если это шаблон. -export const service = define>(); +export const service = annotate>(); -@service.declare(dependency("bar")) +@service.wire() export class Box { private _value: T | undefined; - constructor(value: T) { + constructor(value?: T) { this._value = value; } @@ -20,10 +20,6 @@ export class Box { return value; } - setObj(value: any) { - - } - getValue() { if (this._value === undefined) throw new Error("Trying to get a value from the empty box"); diff --git a/src/test/ts/mock/config.ts b/src/test/ts/mock/config.ts --- a/src/test/ts/mock/config.ts +++ b/src/test/ts/mock/config.ts @@ -1,18 +1,14 @@ -import { configure, dependency, Services, $type } from "./services"; +import { configure, dependency, build } from "./services"; import { Foo } from "./Foo"; import { Bar } from "./Bar"; import { Box } from "./Box"; -import { ConfigBuilder, TypeBuilder } from "../di/fluent/interfaces"; -export declare function build(): TypeBuilder; - -export declare const config: ConfigBuilder; -config +export const config = configure() .register("bar", s => s - .wire(import("./Bar"), "service") + .wired(import("./Bar"), "service") .inject("setName", "heell") ) - .register("box", s => s.wire(import("./Box"))) + .register("box", s => s.wired(import("./Box"))) .register("host", "example.com") // .registerType("bar2", Bar, [{ foo: dependency("foo"), host: "" }]); .register("bar2", s => s.type(Bar, diff --git a/src/test/ts/mock/services.ts b/src/test/ts/mock/services.ts --- a/src/test/ts/mock/services.ts +++ b/src/test/ts/mock/services.ts @@ -1,7 +1,7 @@ import { Foo } from "./Foo"; import { Bar } from "./Bar"; import { Box } from "./Box"; -import { declare } from "../di/Annotations"; +import { declare } from "../di/fluent/interfaces"; /** * Сервисы доступные внутри контейнера @@ -22,4 +22,4 @@ export interface Services { /** * Экспортируем вспомогательные функции для описания сервисов и кинфогурации */ -export const { define, dependency } = declare(); +export const { dependency, build, annotate, configure } = declare();