##// END OF EJS Templates
working on services lifetime
cin -
r130:1af015b1d265 ioc ts support
parent child
Show More
@@ -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 },
26
27 get() {
28 const t = self._cache[id];
29 if (t === undefined)
30 throw new Error(`The item with with the key ${id} isn't found`);
31 return t;
32 },
21 33
22 get(id: string) {
23 const t = this._cache[id];
24 if (t === undefined)
25 throw new Error(`The item with with the key ${id} isn't found`);
26 return t;
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) {
41 argumentNotNull(id, "id");
42 argumentNotNull(item, "item");
43
44 if (this.has())
45 throw new Error(`The item with with the key ${id} already registered with this lifetime manager`);
46 pending = false;
47
48 self._cache[id] = item;
49
50 if (self._destroyed)
51 throw new Error("Lifetime manager is destroyed");
52 if (cleanup) {
53 self._cleanup.push(() => cleanup(item));
54 } else if (isDestroyable(item)) {
55 self._cleanup.push(() => item.destroy());
56 }
57 }
58 };
27 59 }
28 60
29 register(id: string, item: any, cleanup?: (item: any) => void) {
30 argumentNotNull(id, "id");
31 argumentNotNull(item, "item");
32 if (this.has(id))
33 throw new Error(`The item with with the key ${id} already registered with this lifetime manager`);
34 this._cache[id] = item;
61
62
35 63
36 if (this._destroyed)
37 throw new Error("Lifetime manager is destroyed");
38 if (cleanup) {
39 this._cleanup.push(() => cleanup(item));
40 } else if (isDestroyable(item)) {
41 this._cleanup.push(() => item.destroy());
42 }
43 }
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 (target[method] as any)();
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;
@@ -46,6 +46,10 export interface ILifetimeManager extend
46 46
47 47 export interface ILifetime {
48 48 has(): boolean;
49
49 50 get(): any;
51
52 enter(): void;
53
50 54 store(item: any, cleanup?: (item: any) => void): void;
51 55 } No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now