##// END OF EJS Templates
added provided and configure methods to the fluent container configuration, added applyConfig method to the container
cin -
r142:be7edf08a115 v1.4.0-rc3 default
parent child
Show More
@@ -0,0 +1,10
1 import { fluent } from "../di/traits";
2 import { Bar } from "./Bar";
3 import { ChildServices, Services } from "./services";
4
5 export default fluent<ChildServices>()
6 .provided<keyof Services>()
7 .configure({
8 bar: it => it
9 .factory($ => new Bar({ foo: $("foo"), host: $("host") }, "bar"))
10 });
@@ -5,11 +5,11 import { ServiceMap, Descriptor, Partial
5 import { TraceSource } from "../log/TraceSource";
5 import { TraceSource } from "../log/TraceSource";
6 import { Configuration, RegistrationMap } from "./Configuration";
6 import { Configuration, RegistrationMap } from "./Configuration";
7 import { Cancellation } from "../Cancellation";
7 import { Cancellation } from "../Cancellation";
8 import { MapOf, IDestroyable } from "../interfaces";
8 import { IDestroyable, PromiseOrValue, ICancellation } from "../interfaces";
9 import { isDescriptor } from "./traits";
9 import { isDescriptor } from "./traits";
10 import { LifetimeManager } from "./LifetimeManager";
10 import { LifetimeManager } from "./LifetimeManager";
11 import { each } from "../safe";
11 import { each, isString } from "../safe";
12 import { FluentRegistrations } from "./fluent/interfaces";
12 import { ContainerConfiguration, FluentRegistrations } from "./fluent/interfaces";
13 import { FluentConfiguration } from "./fluent/FluentConfiguration";
13 import { FluentConfiguration } from "./fluent/FluentConfiguration";
14
14
15 const trace = TraceSource.get("@implab/core/di/ActivationContext");
15 const trace = TraceSource.get("@implab/core/di/ActivationContext");
@@ -134,6 +134,29 export class Container<S extends object
134 }
134 }
135 }
135 }
136
136
137 applyConfig<S2 extends object>(config: Promise<{ default: ContainerConfiguration<S2>; }>, ct?: ICancellation): Promise<Container<S & S2>>;
138 applyConfig<S2 extends object, P extends string>(config: Promise<{ [p in P]: ContainerConfiguration<S2>; }>, prop: P, ct?: ICancellation): Promise<Container<S & S2>>;
139 async applyConfig<S2 extends object, P extends string>(
140 config: Promise<{ [p in P | "default"]: ContainerConfiguration<S2>; }>,
141 propOrCt?: P | ICancellation,
142 ct?: ICancellation
143 ): Promise<Container<S & S2>> {
144 const mod = await config;
145
146 let _ct: ICancellation;
147 let _prop: P | "default";
148
149 if (isString(propOrCt)) {
150 _prop = propOrCt;
151 _ct = ct || Cancellation.none;
152 } else {
153 _ct = propOrCt || Cancellation.none;
154 _prop = "default";
155 }
156
157 return mod[_prop].apply(this, _ct);
158 }
159
137 async _applyLegacyConfig(config: RegistrationMap<S>, opts: { contextRequire: any; baseModule?: string }, ct = Cancellation.none) {
160 async _applyLegacyConfig(config: RegistrationMap<S>, opts: { contextRequire: any; baseModule?: string }, ct = Cancellation.none) {
138 return new Configuration<S>(this).applyConfiguration(config, opts);
161 return new Configuration<S>(this).applyConfiguration(config, opts);
139 }
162 }
@@ -1,13 +1,17
1 import { Container } from "../Container";
1 import { Container } from "../Container";
2 import { argumentNotNull, each, isPrimitive, isPromise } from "../../safe";
2 import { argumentNotNull, each, isPrimitive, isPromise } from "../../safe";
3 import { DescriptorBuilder } from "./DescriptorBuilder";
3 import { DescriptorBuilder } from "./DescriptorBuilder";
4 import { RegistrationBuilder, FluentRegistrations } from "./interfaces";
4 import { RegistrationBuilder, FluentRegistrations, ContainerConfiguration } from "./interfaces";
5 import { Cancellation } from "../../Cancellation";
5 import { Cancellation } from "../../Cancellation";
6
6
7 export class FluentConfiguration<S extends object, Y extends keyof S = keyof S> {
7 export class FluentConfiguration<S extends object, Y extends keyof S = keyof S> {
8
8
9 _builders: { [k in keyof S]?: RegistrationBuilder<S, S[k]> } = {};
9 _builders: { [k in keyof S]?: RegistrationBuilder<S, S[k]> } = {};
10
10
11 provided<K extends Y>(): FluentConfiguration<S, Exclude<Y, K>> {
12 return this;
13 }
14
11 register<K extends Y>(name: K, builder: RegistrationBuilder<S, S[K]>): FluentConfiguration<S, Exclude<Y, K>>;
15 register<K extends Y>(name: K, builder: RegistrationBuilder<S, S[K]>): FluentConfiguration<S, Exclude<Y, K>>;
12 register<K extends Y>(config: FluentRegistrations<K, S>): FluentConfiguration<S, Exclude<Y, K>>;
16 register<K extends Y>(config: FluentRegistrations<K, S>): FluentConfiguration<S, Exclude<Y, K>>;
13 register<K extends Y>(nameOrConfig: K | FluentRegistrations<K, S>, builder?: RegistrationBuilder<S, S[K]>): FluentConfiguration<S, Exclude<Y, K>> {
17 register<K extends Y>(nameOrConfig: K | FluentRegistrations<K, S>, builder?: RegistrationBuilder<S, S[K]>): FluentConfiguration<S, Exclude<Y, K>> {
@@ -21,6 +25,10 export class FluentConfiguration<S exten
21 return this;
25 return this;
22 }
26 }
23
27
28 configure(config: FluentRegistrations<Y, S>): ContainerConfiguration<S> {
29 return this.register(config);
30 }
31
24 apply<SC extends object>(target: Container<SC>, ct = Cancellation.none) {
32 apply<SC extends object>(target: Container<SC>, ct = Cancellation.none) {
25
33
26 let pending = 1;
34 let pending = 1;
@@ -1,6 +1,7
1 import { primitive } from "../../safe";
1 import { primitive } from "../../safe";
2 import { TypeOfService, ContainerKeys, ActivationType, ILifetime } from "../interfaces";
2 import { TypeOfService, ContainerKeys, ActivationType, ILifetime } from "../interfaces";
3 import { ICancellation } from "../../interfaces";
3 import { ICancellation } from "../../interfaces";
4 import { Container } from "../Container";
4
5
5 export interface DependencyOptions {
6 export interface DependencyOptions {
6 optional?: boolean;
7 optional?: boolean;
@@ -47,6 +48,10 export interface DescriptorBuilder<S ext
47 value(v: T): void;
48 value(v: T): void;
48 }
49 }
49
50
51 export interface ContainerConfiguration<S extends object> {
52 apply<S2 extends object>(target: Container<S2>, ct: ICancellation): Promise<Container<S2 & S>>;
53 }
54
50 export type RegistrationBuilder<S extends object, T> = (d: DescriptorBuilder<S, T>, ct?: ICancellation) => void | Promise<void>;
55 export type RegistrationBuilder<S extends object, T> = (d: DescriptorBuilder<S, T>, ct?: ICancellation) => void | Promise<void>;
51
56
52 export type FluentRegistrations<K extends keyof S, S extends object> = { [k in K]: RegistrationBuilder<S, S[k]> };
57 export type FluentRegistrations<K extends keyof S, S extends object> = { [k in K]: RegistrationBuilder<S, S[k]> };
@@ -151,7 +151,7 export function each(obj: any, cb: any,
151 }
151 }
152
152
153 /** Copies property values from a source object to the destination and returns
153 /** Copies property values from a source object to the destination and returns
154 * the destination onject.
154 * the destination object.
155 *
155 *
156 * @param dest The destination object into which properties from the source
156 * @param dest The destination object into which properties from the source
157 * object will be copied.
157 * object will be copied.
@@ -2,7 +2,7 import { Services } from "./services";
2 import { fluent } from "../di/traits";
2 import { fluent } from "../di/traits";
3 import { Box } from "./Box";
3 import { Box } from "./Box";
4
4
5 export default fluent<Services>().register({
5 export default fluent<Services>().configure({
6 host: it => it.value("example.com"),
6 host: it => it.value("example.com"),
7
7
8 foo: it => import("./Foo").then(({ Foo }) => it
8 foo: it => import("./Foo").then(({ Foo }) => it
@@ -1,6 +1,6
1 import { Foo } from "./Foo";
1 import { Foo } from "./Foo";
2 import { Box } from "./Box";
2 import { Bar } from "./Bar";
3 import { Bar } from "./Bar";
3 import { Box } from "./Box";
4
4
5 /**
5 /**
6 * Сервисы доступные внутри контейнера
6 * Сервисы доступные внутри контейнера
@@ -13,3 +13,10 export interface Services {
13 host: string;
13 host: string;
14
14
15 }
15 }
16
17 export interface ChildServices extends Services {
18
19 foo2?: Foo;
20
21 bar: Bar;
22 }
@@ -61,3 +61,9 test("Load fluent config", async t => {
61
61
62 t.assert(container.resolve("host"), "Should resolve simple value");
62 t.assert(container.resolve("host"), "Should resolve simple value");
63 });
63 });
64
65 test("Container applyConfig", async t => {
66 const container = await new Container<{}>().applyConfig(import("../mock/config"));
67
68 t.assert(container.resolve("host"), "Should resolve simple value");
69 });
@@ -4,7 +4,7
4 "experimentalDecorators": true,
4 "experimentalDecorators": true,
5 "noEmitOnError": true,
5 "noEmitOnError": true,
6 "listFiles": true,
6 "listFiles": true,
7 "strict": true,
7 //"strict": true,
8 "types": [],
8 "types": [],
9 "target": "ES5",
9 "target": "ES5",
10 "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
10 "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
General Comments 0
You need to be logged in to leave comments. Login now