| @@ -14,4 +14,15 | |||||
| 14 | <natures> |
|
14 | <natures> | |
| 15 | <nature>org.eclipse.buildship.core.gradleprojectnature</nature> |
|
15 | <nature>org.eclipse.buildship.core.gradleprojectnature</nature> | |
| 16 | </natures> |
|
16 | </natures> | |
|
|
17 | <filteredResources> | |||
|
|
18 | <filter> | |||
|
|
19 | <id>1599549685358</id> | |||
|
|
20 | <name></name> | |||
|
|
21 | <type>30</type> | |||
|
|
22 | <matcher> | |||
|
|
23 | <id>org.eclipse.core.resources.regexFilterMatcher</id> | |||
|
|
24 | <arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments> | |||
|
|
25 | </matcher> | |||
|
|
26 | </filter> | |||
|
|
27 | </filteredResources> | |||
| 17 | </projectDescription> |
|
28 | </projectDescription> | |
| @@ -185,10 +185,11 export class Configuration<S extends obj | |||||
| 185 | ); |
|
185 | ); | |
| 186 | } |
|
186 | } | |
| 187 |
|
187 | |||
| 188 | async applyConfiguration(data: RegistrationMap<S>, contextRequire?: any, ct = Cancellation.none) { |
|
188 | async applyConfiguration(data: RegistrationMap<S>, opts: { contextRequire?: any; baseModule?: string }, ct = Cancellation.none) { | |
| 189 | argumentNotNull(data, "data"); |
|
189 | argumentNotNull(data, "data"); | |
|
|
190 | const _opts = opts || {}; | |||
| 190 |
|
191 | |||
| 191 |
await this._applyConfiguration(data, await makeResolver( |
|
192 | await this._applyConfiguration(data, await makeResolver(_opts.baseModule, _opts.contextRequire), ct); | |
| 192 | } |
|
193 | } | |
| 193 |
|
194 | |||
| 194 | async _applyConfiguration(data: RegistrationMap<S>, resolver?: ModuleResolver, ct = Cancellation.none) { |
|
195 | async _applyConfiguration(data: RegistrationMap<S>, resolver?: ModuleResolver, ct = Cancellation.none) { | |
| @@ -110,24 +110,34 export class Container<S extends object | |||||
| 110 |
|
110 | |||
| 111 | /** |
|
111 | /** | |
| 112 | * @param{String|Object} config |
|
112 | * @param{String|Object} config | |
| 113 | * The configuration of the contaier. Can be either a string or an object, |
|
113 | * The configuration of the container. Can be either a string or an object, | |
| 114 | * if the configuration is an object it's treated as a collection of |
|
114 | * if the configuration is an object it's treated as a collection of | |
| 115 | * services which will be registed in the contaier. |
|
115 | * services which will be registered in the container. | |
| 116 | * |
|
116 | * | |
| 117 | * @param{Function} opts.contextRequire |
|
117 | * @param{Function} opts.contextRequire | |
| 118 | * The function which will be used to load a configuration or types for services. |
|
118 | * The function which will be used to load a configuration or types for services. | |
| 119 | * |
|
119 | * | |
| 120 | */ |
|
120 | */ | |
| 121 | async configure(config: string | RegistrationMap<S>, opts?: any, ct = Cancellation.none) { |
|
121 | async configure(config: string | RegistrationMap<S>, opts?: { contextRequire: any; baseModule?: string }, ct = Cancellation.none) { | |
| 122 | const c = new Configuration<S>(this); |
|
122 | const _opts = Object.create(opts || null); | |
| 123 |
|
123 | |||
| 124 | if (typeof (config) === "string") { |
|
124 | if (typeof (config) === "string") { | |
| 125 | return c.loadConfiguration(config, opts && opts.contextRequire, ct); |
|
125 | _opts.baseModule = config; | |
|
|
126 | ||||
|
|
127 | const module = await import(config); | |||
|
|
128 | if (module && module.default && typeof (module.default.apply) === "function") | |||
|
|
129 | return module.default.apply(this); | |||
|
|
130 | else | |||
|
|
131 | return this._applyLegacyConfig(module, _opts, ct); | |||
| 126 | } else { |
|
132 | } else { | |
| 127 |
return |
|
133 | return this._applyLegacyConfig(config, _opts, ct); | |
| 128 | } |
|
134 | } | |
| 129 | } |
|
135 | } | |
| 130 |
|
136 | |||
|
|
137 | async _applyLegacyConfig(config: RegistrationMap<S>, opts: { contextRequire: any; baseModule?: string }, ct = Cancellation.none) { | |||
|
|
138 | return new Configuration<S>(this).applyConfiguration(config, opts); | |||
|
|
139 | } | |||
|
|
140 | ||||
| 131 | async fluent<K extends keyof S>(config: FluentRegistrations<K, S>, ct = Cancellation.none): Promise<this> { |
|
141 | async fluent<K extends keyof S>(config: FluentRegistrations<K, S>, ct = Cancellation.none): Promise<this> { | |
| 132 | await new FluentConfiguration<S>().register(config).apply(this, ct); |
|
142 | await new FluentConfiguration<S>().register(config).apply(this, ct); | |
| 133 | return this; |
|
143 | return this; | |
| @@ -21,11 +21,13 export class FluentConfiguration<S exten | |||||
| 21 | return this; |
|
21 | return this; | |
| 22 | } |
|
22 | } | |
| 23 |
|
23 | |||
| 24 | apply(target: Container<S>, ct = Cancellation.none) { |
|
24 | apply<SC extends object>(target: Container<SC>, ct = Cancellation.none) { | |
| 25 |
|
25 | |||
| 26 | let pending = 1; |
|
26 | let pending = 1; | |
| 27 |
|
27 | |||
| 28 | return new Promise((resolve, reject) => { |
|
28 | const _t2 = target as unknown as Container<SC & S>; | |
|
|
29 | ||||
|
|
30 | return new Promise<Container<SC & S>>((resolve, reject) => { | |||
| 29 | function guard(v: void | Promise<void>) { |
|
31 | function guard(v: void | Promise<void>) { | |
| 30 | if (isPromise(v)) |
|
32 | if (isPromise(v)) | |
| 31 | v.catch(reject); |
|
33 | v.catch(reject); | |
| @@ -33,13 +35,13 export class FluentConfiguration<S exten | |||||
| 33 |
|
35 | |||
| 34 | function complete() { |
|
36 | function complete() { | |
| 35 | if (!--pending) |
|
37 | if (!--pending) | |
| 36 | resolve(); |
|
38 | resolve(_t2); | |
| 37 | } |
|
39 | } | |
| 38 | each(this._builders, (v, k) => { |
|
40 | each(this._builders, (v, k) => { | |
| 39 | pending++; |
|
41 | pending++; | |
| 40 |
const d = new DescriptorBuilder<S, any>( |
|
42 | const d = new DescriptorBuilder<SC & S, any>(_t2, | |
| 41 | result => { |
|
43 | result => { | |
| 42 |
|
|
44 | _t2.register(k, result); | |
| 43 | complete(); |
|
45 | complete(); | |
| 44 | }, |
|
46 | }, | |
| 45 | reject |
|
47 | reject | |
| @@ -1,26 +1,14 | |||||
| 1 | import { Services } from "./services"; |
|
1 | import { Services } from "./services"; | |
| 2 | import { fluent } from "../di/traits"; |
|
2 | import { fluent } from "../di/traits"; | |
|
|
3 | import { Box } from "./Box"; | |||
| 3 |
|
4 | |||
| 4 | export default fluent<Services>().register({ |
|
5 | export default fluent<Services>().register({ | |
| 5 | host: it => it.value("example.com"), |
|
6 | host: it => it.value("example.com"), | |
| 6 |
|
7 | |||
| 7 | bar2: it => Promise.all([import("./Foo"), import("./Bar")]) |
|
8 | foo: it => import("./Foo").then(({ Foo }) => it | |
| 8 | .then(([{ Foo }, { Bar }]) => it |
|
9 | .factory(() => new Foo()) | |
| 9 | .lifetime("container") |
|
10 | ), | |
| 10 | .override({ |
|
11 | ||
| 11 | host: it2 => it2.value("simple.org"), |
|
12 | box: it => it | |
| 12 | foo: it2 => it2.value(new Foo()) |
|
13 | .factory($dependency => new Box($dependency("foo"))) | |
| 13 | }) |
|
|||
| 14 | .factory(resolve => { |
|
|||
| 15 | const bar = new Bar({ |
|
|||
| 16 | foo: new Foo(), |
|
|||
| 17 | nested: { |
|
|||
| 18 | lazy: resolve("foo", { lazy: true }) |
|
|||
| 19 | }, |
|
|||
| 20 | host: resolve("host") |
|
|||
| 21 | }, "some text"); |
|
|||
| 22 | bar.setName(resolve("host")); |
|
|||
| 23 | return bar; |
|
|||
| 24 | }) |
|
|||
| 25 | ) |
|
|||
| 26 | }); |
|
14 | }); | |
| @@ -8,11 +8,7 import { Box } from "./Box"; | |||||
| 8 | export interface Services { |
|
8 | export interface Services { | |
| 9 | foo: Foo; |
|
9 | foo: Foo; | |
| 10 |
|
10 | |||
| 11 | bar: Bar; |
|
11 | box: Box<Foo>; | |
| 12 |
|
||||
| 13 | bar2: Bar; |
|
|||
| 14 |
|
||||
| 15 | box: Box<Bar>; |
|
|||
| 16 |
|
12 | |||
| 17 | host: string; |
|
13 | host: string; | |
| 18 |
|
14 | |||
| @@ -5,6 +5,7 import { Container } from "../di/Contain | |||||
| 5 | import { Foo } from "../mock/Foo"; |
|
5 | import { Foo } from "../mock/Foo"; | |
| 6 | import { Box } from "../mock/Box"; |
|
6 | import { Box } from "../mock/Box"; | |
| 7 | import { delay } from "../safe"; |
|
7 | import { delay } from "../safe"; | |
|
|
8 | import { Services } from "../mock/services"; | |||
| 8 |
|
9 | |||
| 9 | test("Simple fluent config", async t => { |
|
10 | test("Simple fluent config", async t => { | |
| 10 | const config = fluent<{ host: string; bar: Bar; foo: Foo }>() |
|
11 | const config = fluent<{ host: string; bar: Bar; foo: Foo }>() | |
| @@ -14,8 +15,8 test("Simple fluent config", async t => | |||||
| 14 | foo: it => import("../mock/Foo").then(m => it.lifetime("container").factory(() => new m.Foo())) |
|
15 | foo: it => import("../mock/Foo").then(m => it.lifetime("container").factory(() => new m.Foo())) | |
| 15 | }); |
|
16 | }); | |
| 16 |
|
17 | |||
| 17 |
const c |
|
18 | const c1 = new Container<{}>(); | |
| 18 |
await config.apply(c |
|
19 | const container = await config.apply(c1); | |
| 19 |
|
20 | |||
| 20 | t.equal(container.resolve("host"), "example.com", "The value should be resolved"); |
|
21 | t.equal(container.resolve("host"), "example.com", "The value should be resolved"); | |
| 21 | t.assert(container.resolve("bar"), "The service should de activated"); |
|
22 | t.assert(container.resolve("bar"), "The service should de activated"); | |
| @@ -52,3 +53,11 test("Bad fluent config", async t => { | |||||
| 52 | t.equal(e.message, "bad override", "the error should pass"); |
|
53 | t.equal(e.message, "bad override", "the error should pass"); | |
| 53 | } |
|
54 | } | |
| 54 | }); |
|
55 | }); | |
|
|
56 | ||||
|
|
57 | test("Load fluent config", async t => { | |||
|
|
58 | const container = new Container<Services>(); | |||
|
|
59 | ||||
|
|
60 | await container.configure("../mock/config", { contextRequire: require }); | |||
|
|
61 | ||||
|
|
62 | t.assert(container.resolve("host"), "Should resolve simple value"); | |||
|
|
63 | }); | |||
General Comments 0
You need to be logged in to leave comments.
Login now
