| @@ -1,6 +1,7 | |||
|
|
1 | 1 | import { IDestroyable, MapOf } from "../interfaces"; |
|
|
2 | 2 | import { argumentNotNull, isDestroyable } from "../safe"; |
|
|
3 | import { ILifetimeManager } from "./interfaces"; | |
|
|
3 | import { ILifetimeManager, ILifetime } from "./interfaces"; | |
|
|
4 | import { ActivationContext } from "./ActivationContext"; | |
|
|
4 | 5 | |
|
|
5 | 6 | function safeCall(item: () => void) { |
|
|
6 | 7 | try { |
| @@ -15,32 +16,53 export class LifetimeManager implements | |||
|
|
15 | 16 | private _cache: MapOf<any> = {}; |
|
|
16 | 17 | private _destroyed = false; |
|
|
17 | 18 | |
|
|
18 | has(id: string) { | |
|
|
19 | return id in this._cache; | |
|
|
20 | } | |
|
|
19 | initialize(id: string, context: ActivationContext<any>): ILifetime { | |
|
|
20 | const self = this; | |
|
|
21 | let pending = false; | |
|
|
22 | return { | |
|
|
23 | has() { | |
|
|
24 | return (id in self._cache); | |
|
|
25 | }, | |
|
|
21 | 26 | |
|
|
22 | get(id: string) { | |
|
|
23 |
const t = |
|
|
|
27 | get() { | |
|
|
28 | const t = self._cache[id]; | |
|
|
24 | 29 | if (t === undefined) |
|
|
25 | 30 | throw new Error(`The item with with the key ${id} isn't found`); |
|
|
26 | 31 | return t; |
|
|
27 | } | |
|
|
32 | }, | |
|
|
28 | 33 | |
|
|
29 | register(id: string, item: any, cleanup?: (item: any) => void) { | |
|
|
34 | enter() { | |
|
|
35 | if (pending) | |
|
|
36 | throw Error(`Cyclic reference detected: the item with the key ${id} is already activating.`); | |
|
|
37 | pending = true; | |
|
|
38 | }, | |
|
|
39 | ||
|
|
40 | store(item: any, cleanup?: (item: any) => void) { | |
|
|
30 | 41 | argumentNotNull(id, "id"); |
|
|
31 | 42 | argumentNotNull(item, "item"); |
|
|
32 | if (this.has(id)) | |
|
|
43 | ||
|
|
44 | if (this.has()) | |
|
|
33 | 45 | throw new Error(`The item with with the key ${id} already registered with this lifetime manager`); |
|
|
34 | this._cache[id] = item; | |
|
|
46 | pending = false; | |
|
|
35 | 47 | |
|
|
36 | if (this._destroyed) | |
|
|
48 | self._cache[id] = item; | |
|
|
49 | ||
|
|
50 | if (self._destroyed) | |
|
|
37 | 51 | throw new Error("Lifetime manager is destroyed"); |
|
|
38 | 52 | if (cleanup) { |
|
|
39 |
|
|
|
|
53 | self._cleanup.push(() => cleanup(item)); | |
|
|
40 | 54 | } else if (isDestroyable(item)) { |
|
|
41 |
|
|
|
|
55 | self._cleanup.push(() => item.destroy()); | |
|
|
42 | 56 | } |
|
|
43 | 57 | } |
|
|
58 | }; | |
|
|
59 | } | |
|
|
60 | ||
|
|
61 | ||
|
|
62 | ||
|
|
63 | ||
|
|
64 | ||
|
|
65 | ||
|
|
44 | 66 | |
|
|
45 | 67 | destroy() { |
|
|
46 | 68 | if (!this._destroyed) { |
| @@ -22,14 +22,15 function injectMethod<T, M extends keyof | |||
|
|
22 | 22 | return m.call(target, _parse(args, context, "." + method)); |
|
|
23 | 23 | } |
|
|
24 | 24 | |
|
|
25 | function makeClenupCallback<T>(method: Cleaner<T>) { | |
|
|
25 | function makeCleanupCallback<T>(method: Cleaner<T>) { | |
|
|
26 | 26 | if (typeof (method) === "function") { |
|
|
27 | 27 | return (target: T) => { |
|
|
28 | 28 | method(target); |
|
|
29 | 29 | }; |
|
|
30 | 30 | } else { |
|
|
31 | 31 | return (target: T) => { |
|
|
32 |
|
|
|
|
32 | const m = target[method] as any; | |
|
|
33 | m.apply(target); | |
|
|
33 | 34 | }; |
|
|
34 | 35 | } |
|
|
35 | 36 | } |
| @@ -102,7 +103,7 export class ServiceDescriptor<S extends | |||
|
|
102 | 103 | throw new Error( |
|
|
103 | 104 | "The cleanup parameter must be either a function or a function name"); |
|
|
104 | 105 | |
|
|
105 | this._cleanup = makeClenupCallback(opts.cleanup); | |
|
|
106 | this._cleanup = makeCleanupCallback(opts.cleanup); | |
|
|
106 | 107 | } |
|
|
107 | 108 | } |
|
|
108 | 109 | |
| @@ -112,6 +113,7 export class ServiceDescriptor<S extends | |||
|
|
112 | 113 | if (lifetime.has()) { |
|
|
113 | 114 | return lifetime.get(); |
|
|
114 | 115 | } else { |
|
|
116 | lifetime.enter(); | |
|
|
115 | 117 | const instance = this._create(context); |
|
|
116 | 118 | lifetime.store(this._cacheId, this._cleanup); |
|
|
117 | 119 | return instance; |
General Comments 0
You need to be logged in to leave comments.
Login now
